import {z} from 'zod' export type GetApiV1ChannelEventArgs = {createdAfter?: string | undefined, eventTypeFilter?: string | undefined}; export type GetApiV1ChannelEventOptions = {baseUrl?: string | undefined, ChannelAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const clientVersion = z.string(); export const sellerEventTypeList = z.enum(["System:Test", "System:Notification", "Seller:Order.Confirmed", "Seller:Order.Shipping", "Seller:Order.Payment", "Seller:Order.Cancellation.Request", "Seller:Order.Cancellation.Accepted", "Seller:Order.Cancellation.Denied", "Seller:Order.Refund", "Seller:Order.Invoice", "Seller:Order.ReturnReceived", "Seller:Offer.New", "Seller:Offer.Update", "Seller:Offer.End", "Seller:Offer.StockUpdate", "Seller:Offer.PriceUpdate", "Seller:Report.Request", "Seller:Channel.Unlinked", "Seller:Meta.SellerAttributesUpdateRequest", "Seller:Ticket.Reply"]); export const sellerId = z.string(); export const channelOrderId = z.string().min(1).max(150); export const orderItemId = z.string().min(1).max(50); export const channel = z.string(); export const offerId = z.number().int().gte(1); export const channelOfferId = z.string().min(1).max(100); export const parentOfferId = z.number().int().gte(1).nullable(); export const quantityPrice = z.object({amount: z.string(), currency: z.string(), quantity: z.string().nullable().optional()}); export const priceContainer = z.object({id: z.string(), quantityPriceList: z.array(quantityPrice)}); export const channelAttribute = z.object({attributeId: z.string(), value: z.string(), group: z.string().nullable().optional()}); export const sKU = z.string().min(1).max(150); export const variation = z.object({offerId: offerId, sku: sKU, gtin: z.string().optional(), variationDimensionList: z.array(channelAttribute), quantity: z.string(), priceList: z.array(priceContainer), taxPercent: z.string().optional(), pictureList: z.array(z.string()).optional(), title: z.string().max(512).optional(), subTitle: z.string().max(1024).optional(), description: z.string().max(50000).optional(), channelAttributeList: z.array(channelAttribute).optional()}); export const price = z.object({amount: z.string(), currency: z.string()}); export const productAttribute = z.object({name: z.string(), value: z.string()}); export const reportType = z.literal("SELLER_INVENTORY"); export const reportId = z.string(); export const orderCancellationRequestId = z.string(); export const cancelReason = z.enum(["BUYER_CANCELLED", "UNDELIVERABLE_TO_SHIPPING_ADDRESS", "UNDELIVERABLE_BY_CARRIER", "OUT_OF_STOCK", "DELAYED_INVENTORY", "PRICING_ERROR", "OTHER"]); export const orderCancellationRequest = z.object({orderCancellationRequestId: orderCancellationRequestId, sellerId: sellerId, orderId: channelOrderId, orderItem: z.array(z.object({orderItemId: orderItemId, quantity: z.string().optional()})).nullable(), cancelReason: cancelReason.optional(), message: z.string().max(1024).optional()}); export const cancellationAccept = z.object({sellerId: sellerId, orderCancellationRequestId: orderCancellationRequestId}); export const cancellationDenied = z.object({sellerId: sellerId, orderCancellationRequestId: orderCancellationRequestId, reason: z.string().max(250)}); export const invoiceDocumentType = z.enum(["INVOICE", "CREDITNOTE"]); export const sellerReturnId = z.string(); export const channelReturnId = z.string(); export const returnReason = z.enum(["NO_REASON", "DEFECT", "WRONG_ITEM", "WRONG_SIZE", "TOO_LATE", "BAD_QUALITY"]); export const condition = z.enum(["ORIGINAL_PACKAGING", "MINT_CONDITION", "SLIGHTLY_USED", "HEAVILY_USED", "DAMAGED", "INCOMPLETE_DELIVERY", "FRAUD"]); export const returnReceivedOrderItem = z.object({orderItemId: orderItemId, quantity: z.string(), returnReason: returnReason, note: z.string().max(1024).optional(), condition: condition, acceptReturn: z.boolean(), requireReturnShipping: z.boolean()}); export const returnReceived = z.object({sellerId: sellerId, orderId: channelOrderId, sellerReturnId: sellerReturnId, channelReturnId: channelReturnId.optional(), orderItem: z.array(returnReceivedOrderItem)}); export const refundId = z.string().min(1).max(128); export const refundReason = z.enum(["NO_REASON", "DEFECT", "WRONG_ITEM", "WRONG_SIZE", "TOO_LATE", "BAD_QUALITY", "OTHER"]); export const refundOrderItem = z.object({orderItemId: orderItemId, quantity: z.string(), reason: refundReason, refund: z.string(), refundCurrency: z.string()}); export const refund = z.object({refundId: refundId, sellerId: sellerId, orderId: channelOrderId, orderItem: z.array(refundOrderItem)}); export const ticketId = z.string().min(1).max(256); export const ticketFrom = z.object({role: z.enum(["BUYER", "SELLER", "CHANNEL"]), name: z.string().max(100).optional()}); export const ticketAttachment = z.object({filename: z.string().min(1).max(256), contentType: z.string().min(1).max(128)}); export const ticketReply = z.object({sellerId: sellerId, ticketId: ticketId, replyRequested: z.boolean().optional(), createdAt: z.string(), from: ticketFrom, message: z.string().min(1).max(1024), attachment: z.array(ticketAttachment).optional()}); export const sellerEventList = z.object({eventList: z.array(z.object({id: z.string(), createdAt: z.string(), clientVersion: clientVersion.optional(), type: sellerEventTypeList, event: z.union([z.object({sellerId: sellerId, orderList: z.array(z.object({sellerId: sellerId, orderId: channelOrderId, shippingComplete: z.boolean(), shippingItems: z.array(z.object({carrier: z.string(), trackingNumber: z.string().optional(), trackingUrl: z.string().optional(), returnTracking: z.object({carrier: z.string(), trackingNumber: z.string(), trackingUrl: z.string().optional()}).nullable().optional(), shippedAt: z.string().optional(), orderItemIdList: z.array(z.object({orderItemId: orderItemId, quantity: z.union([z.number(), z.number().int()])})).nullable().optional(), shippedFrom: z.object({city: z.string(), country: z.string(), postcode: z.string()}).nullable().optional()})), channel: channel})).optional()}), z.object({sellerId: sellerId, orderId: channelOrderId, paymentComplete: z.boolean(), paidAt: z.string()}), z.object({sellerId: sellerId, offerId: offerId, channelOfferId: channelOfferId.optional()}), z.object({sellerId: sellerId, offerId: offerId, parentOfferId: parentOfferId.optional(), channelOfferId: channelOfferId.optional(), channelCategoryId: z.string().optional(), quantity: z.string().optional(), taxPercent: z.string().optional(), priceList: z.array(priceContainer), title: z.string().min(1).max(512).optional(), subTitle: z.string().max(1024).optional(), description: z.string().max(50000).optional(), mainPicture: z.string().optional(), pictureList: z.array(z.string()).optional(), channelAttributeList: z.array(channelAttribute).optional(), variationList: z.array(variation).optional(), sku: sKU, gtin: z.string().optional(), mpn: z.string().optional(), isbn: z.string().optional(), brand: z.string().optional(), srp: price.optional(), productAttributeList: z.array(productAttribute).optional()}), z.object({sellerId: sellerId, offerId: offerId, parentOfferId: parentOfferId.optional(), channelOfferId: channelOfferId.optional(), channelCategoryId: z.string().optional(), quantity: z.string().optional(), taxPercent: z.string().optional(), priceList: z.array(priceContainer), title: z.string().min(1).max(512).optional(), subTitle: z.string().max(1024).optional(), description: z.string().max(50000).optional(), mainPicture: z.string().optional(), pictureList: z.array(z.string()).optional(), channelAttributeList: z.array(channelAttribute).optional(), variationList: z.array(variation).optional(), sku: sKU, gtin: z.string().optional(), mpn: z.string().optional(), isbn: z.string().optional(), brand: z.string().optional(), srp: price.optional(), productAttributeList: z.array(productAttribute).optional()}), z.object({sellerId: sellerId, offerId: offerId, channelOfferId: channelOfferId.optional(), quantity: z.string()}), z.object({sellerId: sellerId, offerId: offerId, channelOfferId: channelOfferId.optional(), priceList: z.array(priceContainer)}), z.object({channel: channel.optional(), sellerId: sellerId.optional()}), z.object({sellerId: sellerId, reportType: reportType, options: z.object({ResultsAsChannelEvent: z.boolean().optional()}).optional(), startDate: z.string().nullable().optional(), endDate: z.string().nullable().optional(), reportId: reportId}), z.object({channel: channel, sellerId: sellerId, message: z.string(), severity: z.enum(["INFO", "WARNING", "ERROR"])}), z.object({sellerId: sellerId, reason: z.string(), unlinkedAt: z.string(), permanentlyRemoved: z.boolean().optional()}), z.object({sellerId: sellerId.optional()}), orderCancellationRequest, cancellationAccept, cancellationDenied, z.object({sellerId: sellerId, orderId: z.string(), orderAccepted: z.boolean().optional(), reason: cancelReason.optional()}), z.object({type: invoiceDocumentType, sellerId: sellerId, orderId: channelOrderId, invoiceNumber: z.string().min(1).max(256), documentId: z.string(), documentExpiresAt: z.string()}), returnReceived, refund, ticketReply])})).optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Seller Events * * * GET /v1/channel/event */ export const getApiV1ChannelEvent = async (args: GetApiV1ChannelEventArgs, options?: GetApiV1ChannelEventOptions) => { const {baseUrl = "https://scx-sbx.api.jtl-software.com", fetch: fetchFn = fetch, ChannelAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.createdAfter != null) query.append("createdAfter", String(args.createdAfter)) if (args.eventTypeFilter != null) query.append("eventTypeFilter", String(args.eventTypeFilter)) if (ChannelAuth !== undefined) headers.set('authorization', `Bearer ${ChannelAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/channel/event${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(sellerEventList, await res.json()) };