import {z} from 'zod' export type GetApiOrdersArgs = {limit?: number | undefined, page?: number | undefined, updated_at_min?: string | undefined, excluded_states?: string | undefined, ship_after_max?: string | undefined, created_at_min?: string | undefined, sort_by?: string | undefined, cursor?: string | undefined, original_order_id?: string | undefined}; export type GetApiOrdersOptions = {baseUrl?: string | undefined, OAuth?: string | undefined, AppCredentials?: string | undefined, fetch?: typeof fetch | undefined}; export const externalOrderV2State = z.enum(["NEW", "PROCESSING", "PRE_TRANSIT", "IN_TRANSIT", "DELIVERED", "CANCELED", "BACKORDERED", "PENDING_RETAILER_CONFIRMATION"]); export const externalOrderItemV2Customization = z.object({token: z.string().optional(), type: z.string().optional(), value: z.string().optional()}); export const externalMoneyV2 = z.object({amount_minor: z.number().int().optional(), currency: z.string().optional()}); export const externalDiscountV2DiscountType = z.enum(["FLAT_AMOUNT", "PERCENTAGE", "NONE"]); export const externalDiscountV2 = z.object({id: z.string().optional(), code: z.string().optional(), discount_type: externalDiscountV2DiscountType.optional(), discount_amount_cents: z.number().int().optional(), discount_percentage: z.number().optional(), includes_free_shipping: z.boolean().optional(), discount_amount: externalMoneyV2.optional()}); export const externalOrderItemV2State = z.enum(["CANCELED", "PROCESSING", "PRE_TRANSIT", "IN_TRANSIT", "DELIVERED", "RETURNED", "BACKORDERED", "DAMAGED_OR_MISSING", "PENDING_RETAILER_CONFIRMATION"]); export const externalOrderItemV2 = z.object({id: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), order_id: z.string().optional(), product_id: z.string().optional(), variant_id: z.string().optional(), quantity: z.number().int().optional(), sku: z.string().optional(), price_cents: z.number().int().optional(), product_name: z.string().optional(), variant_name: z.string().optional(), includes_tester: z.boolean().optional(), tester_price_cents: z.number().int().optional(), customizations: z.array(externalOrderItemV2Customization).optional(), price: externalMoneyV2.optional(), tester_price: externalMoneyV2.optional(), discounts: z.array(externalDiscountV2).optional(), state: externalOrderItemV2State.optional()}); export const externalShipmentV2ExternalShippingType = z.enum(["SHIP_ON_YOUR_OWN", "SHIP_WITH_FAIRE"]); export const externalShipmentV2 = z.object({id: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), order_id: z.string().optional(), maker_cost_cents: z.number().int().optional(), carrier: z.string().optional(), tracking_code: z.string().optional(), maker_cost: externalMoneyV2.optional(), shipping_type: externalShipmentV2ExternalShippingType.optional(), shipping_label_url: z.string().optional(), commercial_invoice_url: z.string().optional()}); export const externalAddressV2AddressType = z.enum(["RESIDENTIAL", "COMMERCIAL", "MIXED"]); export const externalAddressV2 = z.object({id: z.string().optional(), name: z.string().optional(), address1: z.string().optional(), address2: z.string().optional(), postal_code: z.string().optional(), city: z.string().optional(), state: z.string().optional(), state_code: z.string().optional(), phone_number: z.string().optional(), country: z.string().optional(), country_code: z.string().optional(), company_name: z.string().optional(), address_type: externalAddressV2AddressType.optional()}); export const indigofairDataTaxItemTaxableItemType = z.enum(["ORDER_ITEM", "SHIPPING", "INSIDER_MEMBERSHIP", "ORDER_COMMISSION", "ADS_CHARGE", "ORDER_SHIP_WITH_FAIRE"]); export const indigofairDataTaxItemType = z.enum(["CANADIAN_TAX", "VAT", "VAT_REVERSE_CHARGE", "INTRA_COMMUNITY_SUPPLY", "GST", "HST", "PST", "ESTIMATED_IMPORT_VAT", "IMPORT_VAT", "AUSTRALIA_GST", "RECARGO", "RECARGO_REVERSE_CHARGE", "NEW_ZEALAND_GST", "SALES_TAX"]); export const externalTaxItemV2ExternalTaxEffectV2 = z.enum(["INCREASES_PAYOUT", "DEDUCTED_FROM_PAYOUT"]); export const externalTaxItemV2 = z.object({value: externalMoneyV2.optional(), taxable_item_type: indigofairDataTaxItemTaxableItemType.optional(), tax_type: indigofairDataTaxItemType.optional(), effect: externalTaxItemV2ExternalTaxEffectV2.optional()}); export const externalPayoutCostsV2 = z.object({payout_fee_cents: z.number().int().optional(), payout_fee_bps: z.number().int().optional(), payout_flat_fee: externalMoneyV2.optional(), commission_cents: z.number().int().optional(), commission_bps: z.number().int().optional(), commission_flat_fee: externalMoneyV2.optional(), payout_fee: externalMoneyV2.optional(), commission: externalMoneyV2.optional(), total_payout: externalMoneyV2.optional(), payout_protection_fee: externalMoneyV2.optional(), damaged_and_missing_items: externalMoneyV2.optional(), net_tax: externalMoneyV2.optional(), shipping_subsidy: externalMoneyV2.optional(), taxes: z.array(externalTaxItemV2).optional(), subtotal_after_brand_discounts: externalMoneyV2.optional(), total_brand_discounts: externalMoneyV2.optional()}); export const externalOrderV2Customer = z.object({first_name: z.string().optional(), last_name: z.string().optional()}); export const externalOrderV2ExternalFreeShippingReason = z.enum(["INSIDER_FREE_SHIPPING", "FAIRE_DIRECT", "BRAND_DISCOUNT", "FIRST_ORDER", "PROMO_CODE", "FREE_SHIPPING_THRESHOLD"]); export const externalBusinessIdentifierV2 = z.object({identifier_type: z.string().optional(), identifier_value: z.string().optional()}); export const externalOrderV2 = z.object({id: z.string().optional(), display_id: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), state: externalOrderV2State.optional(), items: z.array(externalOrderItemV2).optional(), shipments: z.array(externalShipmentV2).optional(), address: externalAddressV2.optional(), ship_after: z.string().optional(), payout_costs: externalPayoutCostsV2.optional(), payment_initiated_at: z.string().optional(), original_order_id: z.string().optional(), retailer_id: z.string().optional(), source: z.string().optional(), expected_ship_date: z.string().optional(), customer: externalOrderV2Customer.optional(), brand_discounts: z.array(externalDiscountV2).optional(), requested_ship_date: z.string().optional(), processing_at: z.string().optional(), is_free_shipping: z.boolean().optional(), free_shipping_reason: externalOrderV2ExternalFreeShippingReason.optional(), faire_covered_shipping_cost: externalMoneyV2.optional(), estimated_payout_at: z.string().optional(), is_fulfilled_by_faire: z.boolean().optional(), purchase_order_number: z.string().optional(), notes: z.string().optional(), has_pending_retailer_cancellation_request: z.boolean().optional(), sales_rep_name: z.string().optional(), cancelled_at: z.string().optional(), cancellation_initiated_by: z.string().optional(), business_identifiers: z.array(externalBusinessIdentifierV2).optional()}); export const getExternalOrdersResponseV2SortBy = z.enum(["UPDATED_AT", "CREATED_AT"]); export const getExternalOrdersResponseV2 = z.object({orders: z.array(externalOrderV2).optional(), page: z.number().int().optional(), limit: z.number().int().optional(), updated_at_min: z.string().optional(), sort_by: getExternalOrdersResponseV2SortBy.optional(), cursor: z.string().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 }; /** * GET /orders * * GET /orders */ export const getApiOrders = async (args: GetApiOrdersArgs, options?: GetApiOrdersOptions) => { const {baseUrl = "https://www.faire.com/external-api/v2", fetch: fetchFn = fetch, OAuth, AppCredentials} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.limit != null) query.append("limit", String(args.limit)) if (args.page != null) query.append("page", String(args.page)) if (args.updated_at_min != null) query.append("updated_at_min", String(args.updated_at_min)) if (args.excluded_states != null) query.append("excluded_states", String(args.excluded_states)) if (args.ship_after_max != null) query.append("ship_after_max", String(args.ship_after_max)) if (args.created_at_min != null) query.append("created_at_min", String(args.created_at_min)) if (args.sort_by != null) query.append("sort_by", String(args.sort_by)) if (args.cursor != null) query.append("cursor", String(args.cursor)) if (args.original_order_id != null) query.append("original_order_id", String(args.original_order_id)) if (OAuth !== undefined) headers.set("X-FAIRE-OAUTH-ACCESS-TOKEN", OAuth) if (AppCredentials !== undefined) headers.set("X-FAIRE-APP-CREDENTIALS", AppCredentials) const url = `${baseUrl.replace(/\/+$/, '')}/orders${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(getExternalOrdersResponseV2, await res.json()) };