@develemit/commerce-admin 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,7 +62,7 @@ The client calls `${baseUrl}/admin/...`, matching the server's admin routes. `hr
62
62
  The server's `admin.authorize(req)` decides who may call the admin API. Never put an admin token in browser code. Two patterns:
63
63
 
64
64
  1. **Server-side proxy (recommended).** A route handler in your web app checks your own session (for example your login cookie), then forwards the request to the commerce API with the admin token from a server-only env var. The browser client points at the proxy (`baseUrl: '/api'`). See `apps/playground-web/src/app/api/admin/[...path]/route.ts`; it forwards method, query, body (including multipart image uploads) and `idempotency-key`.
65
- 2. **Cookie session.** Serve the commerce API on the same site and have `authorize` read your session cookie. The client then needs no token; use `headers` or a custom `fetch` with `credentials: 'include'` if the API is on another origin.
65
+ 2. **Cookie session.** Serve the commerce API on the same site and have `authorize` read your session cookie. The client then needs no token; use `headers` or a custom `fetch` with `credentials: 'include'` if the API is on another origin. Pass `onUnauthorized(error)` to `createAdminClient` to react when any request answers 401 (for example redirect to your login page when the session expires); the request still rejects with `AdminUnauthorizedError`, and errors thrown by the callback are ignored.
66
66
 
67
67
  ## Primitives
68
68
 
@@ -45,3 +45,6 @@ export declare class DiscountCodeTakenError extends AdminApiError {
45
45
  export declare class DiscountInUseError extends AdminApiError {
46
46
  constructor(url: string, message?: string);
47
47
  }
48
+ export declare class MaxRedemptionsBelowUsageError extends AdminApiError {
49
+ constructor(url: string, message?: string);
50
+ }
@@ -1 +1 @@
1
- export { n as AdminApiError, r as AdminInvalidInputError, i as AdminNotFoundError, a as AdminUnauthorizedError, o as DiscountCodeTakenError, s as DiscountInUseError, c as ImageTooLargeError, l as InsufficientStockError, u as InvalidImageError, d as InvalidOrderStateError, f as RefundExceedsBalanceError, p as RefundGatewayError, m as RefundOutcomeUnknownError, t as createAdminClient } from "../client--_j5r8ag.js";
1
+ export { n as AdminApiError, r as AdminInvalidInputError, i as AdminNotFoundError, a as AdminUnauthorizedError, o as DiscountCodeTakenError, s as DiscountInUseError, c as ImageTooLargeError, l as InsufficientStockError, u as InvalidImageError, d as InvalidOrderStateError, f as MaxRedemptionsBelowUsageError, p as RefundExceedsBalanceError, m as RefundGatewayError, h as RefundOutcomeUnknownError, t as createAdminClient } from "../client-CSjuKdIE.js";
@@ -1,7 +1,9 @@
1
+ import { AdminUnauthorizedError } from './errors';
1
2
  export interface AdminClientOptions {
2
3
  baseUrl: string;
3
4
  fetch?: typeof fetch;
4
5
  headers?: () => HeadersInit | Promise<HeadersInit>;
6
+ onUnauthorized?: (error: AdminUnauthorizedError) => void;
5
7
  }
6
8
  type Schema<T> = {
7
9
  parse(data: unknown): T;
@@ -15,5 +17,5 @@ export interface RequestOptions {
15
17
  export interface Transport {
16
18
  request<T>(path: string, schema: Schema<T>, options?: RequestOptions): Promise<T>;
17
19
  }
18
- export declare function createTransport({ baseUrl, fetch: fetchImpl, headers: getHeaders, }: AdminClientOptions): Transport;
20
+ export declare function createTransport({ baseUrl, fetch: fetchImpl, headers: getHeaders, onUnauthorized, }: AdminClientOptions): Transport;
19
21
  export {};
@@ -60,9 +60,13 @@ var s = class extends Error {
60
60
  constructor(e, t) {
61
61
  super(409, e, "DISCOUNT_IN_USE", t), this.name = "DiscountInUseError";
62
62
  }
63
+ }, b = class extends s {
64
+ constructor(e, t) {
65
+ super(400, e, "MAX_REDEMPTIONS_BELOW_USAGE", t), this.name = "MaxRedemptionsBelowUsageError";
66
+ }
63
67
  };
64
68
  // src/client/map-error.ts
65
- async function b(e) {
69
+ async function x(e) {
66
70
  try {
67
71
  let t = await e.json();
68
72
  return t && typeof t == "object" ? t : {};
@@ -70,70 +74,76 @@ async function b(e) {
70
74
  return {};
71
75
  }
72
76
  }
73
- async function x(e, t) {
74
- let n = await b(t), { error: r, message: i } = n;
75
- return t.status === 401 ? new c(e) : t.status === 404 ? new l(e, r, i) : t.status === 413 ? new _(e) : r === "INVALID_INPUT" ? new u(e, n.issues ?? []) : r === "INVALID_ORDER_STATE" ? new d(e, n.status ?? "", i) : r === "INSUFFICIENT_STOCK" ? new f(e, n.productIds ?? [], i) : r === "REFUND_EXCEEDS_BALANCE" ? new p(e, n.balanceCents, i) : r === "REFUND_GATEWAY_ERROR" ? new m(e, i) : r === "REFUND_OUTCOME_UNKNOWN" ? new h(e, i) : r === "DISCOUNT_CODE_TAKEN" ? new v(e, i) : r === "DISCOUNT_IN_USE" ? new y(e, i) : r === "INVALID_IMAGE" || r === "INVALID_IMAGE_ORDER" ? new g(e, r, i) : new s(t.status, e, r, i);
77
+ async function S(e, t) {
78
+ let n = await x(t), { error: r, message: i } = n;
79
+ return t.status === 401 ? new c(e) : t.status === 404 ? new l(e, r, i) : t.status === 413 ? new _(e) : r === "INVALID_INPUT" ? new u(e, n.issues ?? []) : r === "INVALID_ORDER_STATE" ? new d(e, n.status ?? "", i) : r === "INSUFFICIENT_STOCK" ? new f(e, n.productIds ?? [], i) : r === "REFUND_EXCEEDS_BALANCE" ? new p(e, n.balanceCents, i) : r === "REFUND_GATEWAY_ERROR" ? new m(e, i) : r === "REFUND_OUTCOME_UNKNOWN" ? new h(e, i) : r === "DISCOUNT_CODE_TAKEN" ? new v(e, i) : r === "MAX_REDEMPTIONS_BELOW_USAGE" ? new b(e, i) : r === "DISCOUNT_IN_USE" ? new y(e, i) : r === "INVALID_IMAGE" || r === "INVALID_IMAGE_ORDER" ? new g(e, r, i) : new s(t.status, e, r, i);
76
80
  }
77
81
  // src/client/transport.ts
78
- function S({ baseUrl: e, fetch: t = (...e) => globalThis.fetch(...e), headers: n }) {
79
- let r = e.replace(/\/+$/, "");
80
- return { async request(e, i, { method: a = "GET", body: o, form: s, headers: c } = {}) {
81
- let l = `${r}${e}`, u = new Headers(n ? await n() : void 0);
82
- u.set("accept", "application/json"), o !== void 0 && u.set("content-type", "application/json");
83
- for (let [e, t] of Object.entries(c ?? {})) u.set(e, t);
84
- let d = await t(l, {
85
- method: a,
86
- headers: u,
87
- body: s ?? (o === void 0 ? void 0 : JSON.stringify(o))
82
+ function C({ baseUrl: e, fetch: t = (...e) => globalThis.fetch(...e), headers: n, onUnauthorized: r }) {
83
+ let i = e.replace(/\/+$/, "");
84
+ return { async request(e, a, { method: o = "GET", body: s, form: l, headers: u } = {}) {
85
+ let d = `${i}${e}`, f = new Headers(n ? await n() : void 0);
86
+ f.set("accept", "application/json"), s !== void 0 && f.set("content-type", "application/json");
87
+ for (let [e, t] of Object.entries(u ?? {})) f.set(e, t);
88
+ let p = await t(d, {
89
+ method: o,
90
+ headers: f,
91
+ body: l ?? (s === void 0 ? void 0 : JSON.stringify(s))
88
92
  });
89
- if (!d.ok) throw await x(l, d);
90
- return i.parse(await d.json());
93
+ if (!p.ok) {
94
+ let e = await S(d, p);
95
+ if (e instanceof c) try {
96
+ r?.(e);
97
+ } catch {}
98
+ throw e;
99
+ }
100
+ return a.parse(await p.json());
91
101
  } };
92
102
  }
93
103
  // src/client/admin-client.ts
94
- var C = encodeURIComponent;
95
- function w(e) {
104
+ var w = encodeURIComponent;
105
+ function T(e) {
96
106
  let t = new URLSearchParams();
97
107
  for (let [n, r] of Object.entries(e)) r !== void 0 && t.set(n, String(r));
98
108
  let n = t.toString();
99
109
  return n ? `?${n}` : "";
100
110
  }
101
- function T(s) {
102
- let { request: c } = S(s), l = i, u = a, d = o.array();
111
+ function E(s) {
112
+ let { request: c } = C(s), l = i, u = a, d = o.array();
103
113
  return {
104
- listProducts: (e = {}) => c(`/admin/products${w(e)}`, r),
105
- getProduct: (e) => c(`/admin/products/${C(e)}`, l),
114
+ listProducts: (e = {}) => c(`/admin/products${T(e)}`, r),
115
+ getProduct: (e) => c(`/admin/products/${w(e)}`, l),
106
116
  createProduct: (e) => c("/admin/products", l, {
107
117
  method: "POST",
108
118
  body: e
109
119
  }),
110
- updateProduct: (e, t) => c(`/admin/products/${C(e)}`, l, {
120
+ updateProduct: (e, t) => c(`/admin/products/${w(e)}`, l, {
111
121
  method: "PATCH",
112
122
  body: t
113
123
  }),
114
124
  uploadProductImage(e, t, n) {
115
125
  let r = new FormData();
116
- return n !== void 0 && r.append("alt", n), r.append("file", t), c(`/admin/products/${C(e)}/images`, l, {
126
+ return n !== void 0 && r.append("alt", n), r.append("file", t), c(`/admin/products/${w(e)}/images`, l, {
117
127
  method: "POST",
118
128
  form: r
119
129
  });
120
130
  },
121
- reorderProductImages: (e, t) => c(`/admin/products/${C(e)}/images/order`, l, {
131
+ reorderProductImages: (e, t) => c(`/admin/products/${w(e)}/images/order`, l, {
122
132
  method: "PATCH",
123
133
  body: { imageIds: t }
124
134
  }),
125
- updateProductImage: (e, t, n) => c(`/admin/products/${C(e)}/images/${C(t)}`, l, {
135
+ updateProductImage: (e, t, n) => c(`/admin/products/${w(e)}/images/${w(t)}`, l, {
126
136
  method: "PATCH",
127
137
  body: n
128
138
  }),
129
- deleteProductImage: (e, t) => c(`/admin/products/${C(e)}/images/${C(t)}`, l, { method: "DELETE" }),
130
- listDiscounts: (t = {}) => c(`/admin/discounts${w(t)}`, e),
131
- getDiscount: (e) => c(`/admin/discounts/${C(e)}`, u),
139
+ deleteProductImage: (e, t) => c(`/admin/products/${w(e)}/images/${w(t)}`, l, { method: "DELETE" }),
140
+ listDiscounts: (t = {}) => c(`/admin/discounts${T(t)}`, e),
141
+ getDiscount: (e) => c(`/admin/discounts/${w(e)}`, u),
132
142
  createDiscount: (e) => c("/admin/discounts", u, {
133
143
  method: "POST",
134
144
  body: e
135
145
  }),
136
- updateDiscount: (e, t) => c(`/admin/discounts/${C(e)}`, u, {
146
+ updateDiscount: (e, t) => c(`/admin/discounts/${w(e)}`, u, {
137
147
  method: "PATCH",
138
148
  body: t
139
149
  }),
@@ -142,17 +152,17 @@ function T(s) {
142
152
  method: "PUT",
143
153
  body: e
144
154
  }),
145
- listOrders: (e = {}) => c(`/admin/orders${w(e)}`, n),
146
- getOrder: (e) => c(`/admin/orders/${C(e)}`, t),
147
- shipOrder: (e, n = {}) => c(`/admin/orders/${C(e)}/ship`, t, {
155
+ listOrders: (e = {}) => c(`/admin/orders${T(e)}`, n),
156
+ getOrder: (e) => c(`/admin/orders/${w(e)}`, t),
157
+ shipOrder: (e, n = {}) => c(`/admin/orders/${w(e)}/ship`, t, {
148
158
  method: "POST",
149
159
  body: n
150
160
  }),
151
- resolveOrder: (e) => c(`/admin/orders/${C(e)}/resolve`, t, { method: "POST" }),
161
+ resolveOrder: (e) => c(`/admin/orders/${w(e)}/resolve`, t, { method: "POST" }),
152
162
  async refundOrder(e, n = { restock: !1 }, r = {}) {
153
163
  let i = r.idempotencyKey ?? crypto.randomUUID();
154
164
  try {
155
- return await c(`/admin/orders/${C(e)}/refunds`, t, {
165
+ return await c(`/admin/orders/${w(e)}/refunds`, t, {
156
166
  method: "POST",
157
167
  body: n,
158
168
  headers: { "idempotency-key": i }
@@ -163,6 +173,6 @@ function T(s) {
163
173
  }
164
174
  };
165
175
  }
166
- export { c as a, _ as c, d, p as f, l as i, f as l, h as m, s as n, v as o, m as p, u as r, y as s, T as t, g as u };
176
+ export { c as a, _ as c, d, b as f, h, l as i, f as l, m, s as n, v as o, p, u as r, y as s, E as t, g as u };
167
177
 
168
- //# sourceMappingURL=client--_j5r8ag.js.map
178
+ //# sourceMappingURL=client-CSjuKdIE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-CSjuKdIE.js","names":["AdminApiError","message","status","code","url","AdminUnauthorizedError","AdminNotFoundError","AdminInvalidInputError","issues","InvalidOrderStateError","orderStatus","InsufficientStockError","productIds","RefundExceedsBalanceError","balanceCents","RefundGatewayError","RefundOutcomeUnknownError","InvalidImageError","ImageTooLargeError","DiscountCodeTakenError","DiscountInUseError","MaxRedemptionsBelowUsageError","readBody","body","res","mapError","createTransport","fetchImpl","args","getHeaders","root","baseUrl","path","merged","name","value","headers","form","error","schema","enc","queryString","params","key","query","qs","createAdminClient","options","product","adminProductSchema","discount","discountSchema","rates","shippingRateSchema","request","adminProductPageSchema","id","input","patch","alt","file","imageId","adminDiscountPageSchema","adminOrderPageSchema","adminOrderDetailSchema","refund","err"],"sources":["../src/client/errors.ts","../src/client/map-error.ts","../src/client/transport.ts","../src/client/admin-client.ts"],"sourcesContent":["export class AdminApiError extends Error {\n idempotencyKey?: string;\n\n constructor(\n readonly status: number,\n readonly url: string,\n readonly code?: string,\n message?: string,\n ) {\n super(\n message ??\n `Admin API request failed (${status}${code ? ` ${code}` : ''}): ${url}`,\n );\n this.name = 'AdminApiError';\n }\n}\n\nexport class AdminUnauthorizedError extends AdminApiError {\n constructor(url: string) {\n super(401, url, 'UNAUTHORIZED', `Not authorized: ${url}`);\n this.name = 'AdminUnauthorizedError';\n }\n}\n\nexport class AdminNotFoundError extends AdminApiError {\n constructor(url: string, code?: string, message?: string) {\n super(404, url, code, message ?? `Not found: ${url}`);\n this.name = 'AdminNotFoundError';\n }\n}\n\nexport class AdminInvalidInputError extends AdminApiError {\n constructor(\n url: string,\n readonly issues: unknown[],\n ) {\n super(400, url, 'INVALID_INPUT', `Invalid input: ${url}`);\n this.name = 'AdminInvalidInputError';\n }\n}\n\nexport class InvalidOrderStateError extends AdminApiError {\n constructor(\n url: string,\n readonly orderStatus: string,\n message?: string,\n ) {\n super(409, url, 'INVALID_ORDER_STATE', message);\n this.name = 'InvalidOrderStateError';\n }\n}\n\nexport class InsufficientStockError extends AdminApiError {\n constructor(\n url: string,\n readonly productIds: string[],\n message?: string,\n ) {\n super(409, url, 'INSUFFICIENT_STOCK', message);\n this.name = 'InsufficientStockError';\n }\n}\n\nexport class RefundExceedsBalanceError extends AdminApiError {\n constructor(\n url: string,\n readonly balanceCents: number | undefined,\n message?: string,\n ) {\n super(400, url, 'REFUND_EXCEEDS_BALANCE', message);\n this.name = 'RefundExceedsBalanceError';\n }\n}\n\nexport class RefundGatewayError extends AdminApiError {\n constructor(url: string, message?: string) {\n super(502, url, 'REFUND_GATEWAY_ERROR', message);\n this.name = 'RefundGatewayError';\n }\n}\n\nexport class RefundOutcomeUnknownError extends AdminApiError {\n constructor(url: string, message?: string) {\n super(502, url, 'REFUND_OUTCOME_UNKNOWN', message);\n this.name = 'RefundOutcomeUnknownError';\n }\n}\n\nexport class InvalidImageError extends AdminApiError {\n constructor(url: string, code: string, message?: string) {\n super(400, url, code, message);\n this.name = 'InvalidImageError';\n }\n}\n\nexport class ImageTooLargeError extends AdminApiError {\n constructor(url: string) {\n super(413, url, 'IMAGE_TOO_LARGE', `Image is too large: ${url}`);\n this.name = 'ImageTooLargeError';\n }\n}\n\nexport class DiscountCodeTakenError extends AdminApiError {\n constructor(url: string, message?: string) {\n super(409, url, 'DISCOUNT_CODE_TAKEN', message);\n this.name = 'DiscountCodeTakenError';\n }\n}\n\nexport class DiscountInUseError extends AdminApiError {\n constructor(url: string, message?: string) {\n super(409, url, 'DISCOUNT_IN_USE', message);\n this.name = 'DiscountInUseError';\n }\n}\n\nexport class MaxRedemptionsBelowUsageError extends AdminApiError {\n constructor(url: string, message?: string) {\n super(400, url, 'MAX_REDEMPTIONS_BELOW_USAGE', message);\n this.name = 'MaxRedemptionsBelowUsageError';\n }\n}\n","import {\n AdminApiError,\n AdminInvalidInputError,\n AdminNotFoundError,\n AdminUnauthorizedError,\n DiscountCodeTakenError,\n DiscountInUseError,\n ImageTooLargeError,\n InsufficientStockError,\n InvalidImageError,\n InvalidOrderStateError,\n MaxRedemptionsBelowUsageError,\n RefundExceedsBalanceError,\n RefundGatewayError,\n RefundOutcomeUnknownError,\n} from './errors';\n\ninterface ErrorBody {\n error?: string;\n message?: string;\n issues?: unknown[];\n status?: string;\n productIds?: string[];\n balanceCents?: number;\n}\n\nasync function readBody(res: Response): Promise<ErrorBody> {\n try {\n const body: unknown = await res.json();\n return body && typeof body === 'object' ? (body as ErrorBody) : {};\n } catch {\n return {};\n }\n}\n\nexport async function mapError(\n url: string,\n res: Response,\n): Promise<AdminApiError> {\n const body = await readBody(res);\n const { error: code, message } = body;\n if (res.status === 401) return new AdminUnauthorizedError(url);\n if (res.status === 404) return new AdminNotFoundError(url, code, message);\n if (res.status === 413) return new ImageTooLargeError(url);\n if (code === 'INVALID_INPUT') {\n return new AdminInvalidInputError(url, body.issues ?? []);\n }\n if (code === 'INVALID_ORDER_STATE') {\n return new InvalidOrderStateError(url, body.status ?? '', message);\n }\n if (code === 'INSUFFICIENT_STOCK') {\n return new InsufficientStockError(url, body.productIds ?? [], message);\n }\n if (code === 'REFUND_EXCEEDS_BALANCE') {\n return new RefundExceedsBalanceError(url, body.balanceCents, message);\n }\n if (code === 'REFUND_GATEWAY_ERROR')\n return new RefundGatewayError(url, message);\n if (code === 'REFUND_OUTCOME_UNKNOWN') {\n return new RefundOutcomeUnknownError(url, message);\n }\n if (code === 'DISCOUNT_CODE_TAKEN') {\n return new DiscountCodeTakenError(url, message);\n }\n if (code === 'MAX_REDEMPTIONS_BELOW_USAGE') {\n return new MaxRedemptionsBelowUsageError(url, message);\n }\n if (code === 'DISCOUNT_IN_USE') return new DiscountInUseError(url, message);\n if (code === 'INVALID_IMAGE' || code === 'INVALID_IMAGE_ORDER') {\n return new InvalidImageError(url, code, message);\n }\n return new AdminApiError(res.status, url, code, message);\n}\n","import { AdminUnauthorizedError } from './errors';\nimport { mapError } from './map-error';\n\nexport interface AdminClientOptions {\n baseUrl: string;\n fetch?: typeof fetch;\n headers?: () => HeadersInit | Promise<HeadersInit>;\n onUnauthorized?: (error: AdminUnauthorizedError) => void;\n}\n\ntype Schema<T> = { parse(data: unknown): T };\n\nexport interface RequestOptions {\n method?: string;\n body?: unknown;\n form?: FormData;\n headers?: Record<string, string>;\n}\n\nexport interface Transport {\n request<T>(\n path: string,\n schema: Schema<T>,\n options?: RequestOptions,\n ): Promise<T>;\n}\n\nexport function createTransport({\n baseUrl,\n fetch: fetchImpl = (...args) => globalThis.fetch(...args),\n headers: getHeaders,\n onUnauthorized,\n}: AdminClientOptions): Transport {\n const root = baseUrl.replace(/\\/+$/, '');\n\n return {\n async request(path, schema, { method = 'GET', body, form, headers } = {}) {\n const url = `${root}${path}`;\n const merged = new Headers(getHeaders ? await getHeaders() : undefined);\n merged.set('accept', 'application/json');\n if (body !== undefined) merged.set('content-type', 'application/json');\n for (const [name, value] of Object.entries(headers ?? {})) {\n merged.set(name, value);\n }\n const res = await fetchImpl(url, {\n method,\n headers: merged,\n body: form ?? (body === undefined ? undefined : JSON.stringify(body)),\n });\n if (!res.ok) {\n const error = await mapError(url, res);\n if (error instanceof AdminUnauthorizedError) {\n try {\n onUnauthorized?.(error);\n } catch {\n // A host callback failure must not replace the 401 the caller expects.\n }\n }\n throw error;\n }\n return schema.parse(await res.json());\n },\n };\n}\n","import {\n adminDiscountPageSchema,\n adminOrderDetailSchema,\n adminOrderPageSchema,\n adminProductPageSchema,\n adminProductSchema,\n discountSchema,\n shippingRateSchema,\n type AdminDiscountListQuery,\n type AdminDiscountPage,\n type AdminOrderDetail,\n type AdminOrderListQuery,\n type AdminOrderPage,\n type AdminProduct,\n type AdminProductListQuery,\n type AdminProductPage,\n type AdminProductInput,\n type AdminProductPatch,\n type Discount,\n type DiscountInput,\n type DiscountPatch,\n type RefundOrderInput,\n type ProductImagePatch,\n type ShippingRate,\n type ShippingRateInput,\n type ShipOrderInput,\n} from '@develemit/commerce-contracts';\nimport { createTransport, type AdminClientOptions } from './transport';\n\nexport type AdminOrderQuery = Partial<\n Pick<AdminOrderListQuery, 'status' | 'q' | 'hasPendingRefund' | 'cursor'>\n> & { limit?: number };\n\nexport type AdminProductQuery = Pick<\n AdminProductListQuery,\n 'status' | 'stock' | 'q' | 'cursor' | 'limit'\n>;\n\nexport type AdminDiscountQuery = Partial<\n Pick<AdminDiscountListQuery, 'status' | 'q' | 'cursor' | 'limit'>\n>;\n\nexport interface RefundOptions {\n idempotencyKey?: string;\n}\n\nexport interface AdminClient {\n listProducts(query?: AdminProductQuery): Promise<AdminProductPage>;\n getProduct(id: string): Promise<AdminProduct>;\n createProduct(input: AdminProductInput): Promise<AdminProduct>;\n updateProduct(id: string, patch: AdminProductPatch): Promise<AdminProduct>;\n uploadProductImage(\n id: string,\n file: Blob,\n alt?: string,\n ): Promise<AdminProduct>;\n reorderProductImages(id: string, imageIds: string[]): Promise<AdminProduct>;\n updateProductImage(\n id: string,\n imageId: string,\n patch: ProductImagePatch,\n ): Promise<AdminProduct>;\n deleteProductImage(id: string, imageId: string): Promise<AdminProduct>;\n listDiscounts(query?: AdminDiscountQuery): Promise<AdminDiscountPage>;\n getDiscount(id: string): Promise<Discount>;\n createDiscount(input: DiscountInput): Promise<Discount>;\n updateDiscount(id: string, patch: DiscountPatch): Promise<Discount>;\n listShippingRates(): Promise<ShippingRate[]>;\n replaceShippingRates(rates: ShippingRateInput[]): Promise<ShippingRate[]>;\n listOrders(query?: AdminOrderQuery): Promise<AdminOrderPage>;\n getOrder(id: string): Promise<AdminOrderDetail>;\n shipOrder(id: string, input?: ShipOrderInput): Promise<AdminOrderDetail>;\n resolveOrder(id: string): Promise<AdminOrderDetail>;\n /**\n * Retrying the same intent must reuse the same key. When none is passed one\n * is generated, and it is set on any thrown error as `idempotencyKey` so the\n * caller can pass it back on retry.\n */\n refundOrder(\n id: string,\n input?: RefundOrderInput,\n options?: RefundOptions,\n ): Promise<AdminOrderDetail>;\n}\n\nconst enc = encodeURIComponent;\n\nfunction queryString(query: object): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) params.set(key, String(value));\n }\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n}\n\nexport function createAdminClient(options: AdminClientOptions): AdminClient {\n const { request } = createTransport(options);\n const product = adminProductSchema;\n const discount = discountSchema;\n const rates = shippingRateSchema.array();\n\n return {\n listProducts: (query = {}) =>\n request(`/admin/products${queryString(query)}`, adminProductPageSchema),\n getProduct: (id) => request(`/admin/products/${enc(id)}`, product),\n createProduct: (input) =>\n request('/admin/products', product, { method: 'POST', body: input }),\n updateProduct: (id, patch) =>\n request(`/admin/products/${enc(id)}`, product, {\n method: 'PATCH',\n body: patch,\n }),\n uploadProductImage(id, file, alt) {\n const form = new FormData();\n if (alt !== undefined) form.append('alt', alt);\n form.append('file', file);\n return request(`/admin/products/${enc(id)}/images`, product, {\n method: 'POST',\n form,\n });\n },\n reorderProductImages: (id, imageIds) =>\n request(`/admin/products/${enc(id)}/images/order`, product, {\n method: 'PATCH',\n body: { imageIds },\n }),\n updateProductImage: (id, imageId, patch) =>\n request(`/admin/products/${enc(id)}/images/${enc(imageId)}`, product, {\n method: 'PATCH',\n body: patch,\n }),\n deleteProductImage: (id, imageId) =>\n request(`/admin/products/${enc(id)}/images/${enc(imageId)}`, product, {\n method: 'DELETE',\n }),\n listDiscounts: (query = {}) =>\n request(`/admin/discounts${queryString(query)}`, adminDiscountPageSchema),\n getDiscount: (id) => request(`/admin/discounts/${enc(id)}`, discount),\n createDiscount: (input) =>\n request('/admin/discounts', discount, { method: 'POST', body: input }),\n updateDiscount: (id, patch) =>\n request(`/admin/discounts/${enc(id)}`, discount, {\n method: 'PATCH',\n body: patch,\n }),\n listShippingRates: () => request('/admin/shipping-rates', rates),\n replaceShippingRates: (input) =>\n request('/admin/shipping-rates', rates, { method: 'PUT', body: input }),\n listOrders: (query = {}) =>\n request(`/admin/orders${queryString(query)}`, adminOrderPageSchema),\n getOrder: (id) =>\n request(`/admin/orders/${enc(id)}`, adminOrderDetailSchema),\n shipOrder: (id, input = {}) =>\n request(`/admin/orders/${enc(id)}/ship`, adminOrderDetailSchema, {\n method: 'POST',\n body: input,\n }),\n resolveOrder: (id) =>\n request(`/admin/orders/${enc(id)}/resolve`, adminOrderDetailSchema, {\n method: 'POST',\n }),\n async refundOrder(id, input = { restock: false }, refund = {}) {\n const key = refund.idempotencyKey ?? crypto.randomUUID();\n try {\n return await request(\n `/admin/orders/${enc(id)}/refunds`,\n adminOrderDetailSchema,\n {\n method: 'POST',\n body: input,\n headers: { 'idempotency-key': key },\n },\n );\n } catch (err) {\n if (err instanceof Error) {\n (err as Error & { idempotencyKey?: string }).idempotencyKey = key;\n }\n throw err;\n }\n },\n };\n}\n"],"mappings":"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"}