@ordersail/storefront-sdk 0.1.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 +124 -0
- package/dist/http.d.ts +20 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +28 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/cart.d.ts +83 -0
- package/dist/resources/cart.d.ts.map +1 -0
- package/dist/resources/cart.js +54 -0
- package/dist/resources/cart.js.map +1 -0
- package/dist/resources/checkout.d.ts +21 -0
- package/dist/resources/checkout.d.ts.map +1 -0
- package/dist/resources/checkout.js +33 -0
- package/dist/resources/checkout.js.map +1 -0
- package/dist/resources/customer.d.ts +24 -0
- package/dist/resources/customer.d.ts.map +1 -0
- package/dist/resources/customer.js +14 -0
- package/dist/resources/customer.js.map +1 -0
- package/dist/resources/products.d.ts +67 -0
- package/dist/resources/products.d.ts.map +1 -0
- package/dist/resources/products.js +16 -0
- package/dist/resources/products.js.map +1 -0
- package/dist/types.gen.d.ts +979 -0
- package/dist/types.gen.d.ts.map +1 -0
- package/dist/types.gen.js +6 -0
- package/dist/types.gen.js.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# @ordersail/storefront-sdk
|
|
2
|
+
|
|
3
|
+
A typed TypeScript client for OrderSail's public `storefront-api`. This is
|
|
4
|
+
the thing a merchant (or their developer) uses to build and host their
|
|
5
|
+
**own** storefront against OrderSail's catalog, cart, checkout, and customer
|
|
6
|
+
account data — `storefront-web` is just the worked reference example of
|
|
7
|
+
doing that.
|
|
8
|
+
|
|
9
|
+
Generated types come straight from `storefront-api`'s OpenAPI spec
|
|
10
|
+
(`src/types.gen.ts`); everything else is a thin, hand-written wrapper for
|
|
11
|
+
ergonomics around [`openapi-fetch`](https://openapi-ts.dev/openapi-fetch/).
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @ordersail/storefront-sdk
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Inside this monorepo it's consumed via the npm workspace protocol instead
|
|
20
|
+
(see `apps/storefront-web/package.json`).
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { StorefrontClient, ApiError } from "@ordersail/storefront-sdk";
|
|
26
|
+
|
|
27
|
+
const storefrontApi = new StorefrontClient(
|
|
28
|
+
"https://api.your-storefront-api-host.com",
|
|
29
|
+
"sfk_...", // your account's app key — see "Auth model" below
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// reads return the data directly, or undefined if not found
|
|
33
|
+
const products = await storefrontApi.products.list({ limit: 20 });
|
|
34
|
+
|
|
35
|
+
// mutations throw a typed ApiError on failure
|
|
36
|
+
try {
|
|
37
|
+
await storefrontApi.cart.addItem({ variantId: 123, quantity: 1 });
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error instanceof ApiError) {
|
|
40
|
+
console.error(`${error.status}: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Resources
|
|
46
|
+
|
|
47
|
+
| Resource | Method | Throws `ApiError`? |
|
|
48
|
+
| ------------------------------ | ---------------------------------------- | ------------------- |
|
|
49
|
+
| `storefrontApi.products` | `list(query?)` | no |
|
|
50
|
+
| | `getById(id)` | no |
|
|
51
|
+
| `storefrontApi.cart` | `get()` | no |
|
|
52
|
+
| | `addItem(body)` | **yes** |
|
|
53
|
+
| | `updateItem(variantId, body)` | **yes** |
|
|
54
|
+
| | `removeItem(variantId)` | **yes** |
|
|
55
|
+
| | `clear()` | **yes** |
|
|
56
|
+
| `storefrontApi.checkout` | `getConfig()` | no |
|
|
57
|
+
| | `createSession(body)` | **yes** |
|
|
58
|
+
| | `getSessionStatus(sessionId)` | no |
|
|
59
|
+
| | `getShippingOptions(body)` | no |
|
|
60
|
+
| `storefrontApi.customer` | `get()` | no |
|
|
61
|
+
| | `update(params)` | **yes** |
|
|
62
|
+
| `storefrontApi` (top level) | `signUp(dto)` | **yes** |
|
|
63
|
+
| | `signIn(credentials)` | **yes** |
|
|
64
|
+
| | `refreshAccessToken()` | no |
|
|
65
|
+
| | `logout()` | no |
|
|
66
|
+
|
|
67
|
+
The convention throughout: a read returns the response body directly (or
|
|
68
|
+
`undefined` on a non-2xx response), while a mutation throws `ApiError` so a
|
|
69
|
+
failure can't be silently ignored.
|
|
70
|
+
|
|
71
|
+
Not yet supported: **order history** for customers (`storefront-api` has no
|
|
72
|
+
customer-facing order endpoints yet — see Storefront Builder M5) and
|
|
73
|
+
**webhooks/real-time events** (no plans yet).
|
|
74
|
+
|
|
75
|
+
## Error handling
|
|
76
|
+
|
|
77
|
+
Every mutation throws `ApiError` (from `@ordersail/storefront-sdk`) on a
|
|
78
|
+
non-2xx response:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
export class ApiError extends Error {
|
|
82
|
+
readonly status: number; // the HTTP status code
|
|
83
|
+
readonly message: string; // the server's message, when it sends one
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`error.message` is the API's own message when the response body has one
|
|
88
|
+
(most validation and conflict errors do); otherwise it falls back to
|
|
89
|
+
`` `Request failed (${status})` ``. Two exceptions worth knowing: `signIn`'s
|
|
90
|
+
`401` and `signUp`'s `409` currently carry no response body at all, so
|
|
91
|
+
`error.message` for those two is always the generic fallback — write your
|
|
92
|
+
own copy for those cases rather than surfacing it (see
|
|
93
|
+
`apps/storefront-web/src/routes/signin.tsx` for the pattern).
|
|
94
|
+
|
|
95
|
+
## Auth model
|
|
96
|
+
|
|
97
|
+
Two independent layers, both handled for you by `StorefrontClient`:
|
|
98
|
+
|
|
99
|
+
- **Tenant scoping** — every request carries an `x-app-key` header (your
|
|
100
|
+
account's app key, created in `merchant-web` under Settings → Developer
|
|
101
|
+
API keys). Set once in the constructor; re-assign `client.appKey` later if
|
|
102
|
+
you ever need to switch accounts.
|
|
103
|
+
- **Customer auth** — a bearer JWT (`accessToken`), held in memory only (it
|
|
104
|
+
doesn't survive a page reload), plus an httpOnly `customer_refresh_token`
|
|
105
|
+
cookie the browser sends automatically (`credentials: "include"`). Call
|
|
106
|
+
`refreshAccessToken()` on app start to restore a session from that cookie.
|
|
107
|
+
|
|
108
|
+
**Known gap**: only `customer.get()`/`customer.update()` currently retry
|
|
109
|
+
once on a `401` by calling `refreshAccessToken()` and re-issuing the
|
|
110
|
+
request. `cart` and `checkout` methods do not — if you're calling them a
|
|
111
|
+
long time after the last customer request, a stale in-memory token can
|
|
112
|
+
produce an unhandled `401`. Call `refreshAccessToken()` proactively if this
|
|
113
|
+
matters for your integration, or treat it as a signed-out state and prompt
|
|
114
|
+
sign-in again.
|
|
115
|
+
|
|
116
|
+
## Regenerating after an API change
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm run generate:openapi -w storefront-api # refresh storefront-api's openapi.json
|
|
120
|
+
npm run generate -w @ordersail/storefront-sdk # regenerate types.gen.ts from it
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Both steps are manual and their output is committed — there's no watch mode
|
|
124
|
+
or CI auto-regen.
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type DoRequest<T> = () => Promise<{
|
|
2
|
+
data?: T;
|
|
3
|
+
error?: unknown;
|
|
4
|
+
response: Response;
|
|
5
|
+
}>;
|
|
6
|
+
export type DoFn = <T>(request: DoRequest<T>) => Promise<{
|
|
7
|
+
data?: T;
|
|
8
|
+
error?: unknown;
|
|
9
|
+
response: Response;
|
|
10
|
+
}>;
|
|
11
|
+
export declare class ApiError extends Error {
|
|
12
|
+
readonly status: number;
|
|
13
|
+
constructor(message: string, status: number);
|
|
14
|
+
}
|
|
15
|
+
export declare function unwrap<T>(result: {
|
|
16
|
+
data?: T;
|
|
17
|
+
error?: unknown;
|
|
18
|
+
response: Response;
|
|
19
|
+
}): T;
|
|
20
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;CACpB,CAAC,CAAC;AAKH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,EACnB,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAClB,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAIhE,qBAAa,QAAS,SAAQ,KAAK;IAG/B,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM;CAK1B;AAKD,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE;IAChC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;CACpB,GAAG,CAAC,CAaJ"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// A non-2xx response from the API. `message` is the server's message when it
|
|
2
|
+
// sends one (NestJS `{ message }`, string or string[]), otherwise a fallback.
|
|
3
|
+
export class ApiError extends Error {
|
|
4
|
+
status;
|
|
5
|
+
constructor(message, status) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.name = "ApiError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
// openapi-fetch resolves non-2xx as { error } rather than throwing. Resource
|
|
12
|
+
// methods that mutate use this so callers can `try/catch` and show the API's
|
|
13
|
+
// message instead of a generic string.
|
|
14
|
+
export function unwrap(result) {
|
|
15
|
+
if (result.data !== undefined)
|
|
16
|
+
return result.data;
|
|
17
|
+
const body = result.error;
|
|
18
|
+
const raw = body && typeof body === "object" && "message" in body
|
|
19
|
+
? body.message
|
|
20
|
+
: undefined;
|
|
21
|
+
const message = Array.isArray(raw)
|
|
22
|
+
? raw.join(", ")
|
|
23
|
+
: typeof raw === "string" && raw
|
|
24
|
+
? raw
|
|
25
|
+
: `Request failed (${result.response.status})`;
|
|
26
|
+
throw new ApiError(message, result.response.status);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAaA,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGtB;IAFX,YACE,OAAe,EACN,MAAc;QAEvB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,WAAM,GAAN,MAAM,CAAQ;QAGvB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,6EAA6E;AAC7E,6EAA6E;AAC7E,uCAAuC;AACvC,MAAM,UAAU,MAAM,CAAI,MAIzB;IACC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;IAC1B,MAAM,GAAG,GACP,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,SAAS,IAAI,IAAI;QACnD,CAAC,CAAE,IAA6B,CAAC,OAAO;QACxC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAChC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;QAChB,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG;YAC9B,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,mBAAmB,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;IACnD,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACtD,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Client } from "openapi-fetch";
|
|
2
|
+
import type { paths, components } from "./types.gen.js";
|
|
3
|
+
export { ApiError } from "./http.js";
|
|
4
|
+
import { createProductsResource } from "./resources/products.js";
|
|
5
|
+
import { createCartResource } from "./resources/cart.js";
|
|
6
|
+
import { createCheckoutResource } from "./resources/checkout.js";
|
|
7
|
+
import { createCustomerResource } from "./resources/customer.js";
|
|
8
|
+
export type ProductListItem = components["schemas"]["ProductListItem"];
|
|
9
|
+
export type PaginatedProducts = components["schemas"]["PaginatedProducts"];
|
|
10
|
+
export type ProductDetail = components["schemas"]["ProductDetail"];
|
|
11
|
+
export type ProductDetailOption = components["schemas"]["ProductDetailOption"];
|
|
12
|
+
export type ProductDetailVariant = components["schemas"]["ProductDetailVariant"];
|
|
13
|
+
export type Cart = components["schemas"]["Cart"];
|
|
14
|
+
export type CartItem = components["schemas"]["CartItem"];
|
|
15
|
+
export type CheckoutSession = components["schemas"]["CheckoutSession"];
|
|
16
|
+
export type CheckoutConfig = components["schemas"]["CheckoutConfig"];
|
|
17
|
+
export type CheckoutSessionStatus = components["schemas"]["CheckoutSessionStatus"];
|
|
18
|
+
export type Customer = components["schemas"]["Customer"];
|
|
19
|
+
export type CustomerSignUpDto = components["schemas"]["CustomerSignUpDto"];
|
|
20
|
+
export type CustomerSignInDto = components["schemas"]["CustomerSignInDto"];
|
|
21
|
+
export type UpdateCustomerDto = components["schemas"]["UpdateCustomerDto"];
|
|
22
|
+
export declare class StorefrontClient {
|
|
23
|
+
appKey: string;
|
|
24
|
+
cartToken: string | undefined;
|
|
25
|
+
accessToken: string | undefined;
|
|
26
|
+
client: Client<paths>;
|
|
27
|
+
products: ReturnType<typeof createProductsResource>;
|
|
28
|
+
cart: ReturnType<typeof createCartResource>;
|
|
29
|
+
checkout: ReturnType<typeof createCheckoutResource>;
|
|
30
|
+
customer: ReturnType<typeof createCustomerResource>;
|
|
31
|
+
private authMiddleware;
|
|
32
|
+
constructor(baseUrl: string, appKey: string, cartToken?: string);
|
|
33
|
+
signUp(signup: CustomerSignUpDto): Promise<string>;
|
|
34
|
+
signIn(credentials: CustomerSignInDto): Promise<string>;
|
|
35
|
+
refreshAccessToken(): Promise<string | undefined>;
|
|
36
|
+
logout(): Promise<void>;
|
|
37
|
+
private do;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAqB,EAAE,KAAK,MAAM,EAAmB,MAAM,eAAe,CAAC;AAC3E,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACvE,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,mBAAmB,CAAC,CAAC;AAC3E,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC;AACnE,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC;AAC/E,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,sBAAsB,CAAC,CAAC;AACjF,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AACjD,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC;AACzD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACvE,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,qBAAqB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,uBAAuB,CAAC,CAAC;AACnF,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC;AACzD,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,mBAAmB,CAAC,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,mBAAmB,CAAC,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,mBAAmB,CAAC,CAAC;AAI3E,qBAAa,gBAAgB;IAC3B,MAAM,EAAE,MAAM,CAAC;IAGf,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAG9B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAEtB,QAAQ,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IACpD,IAAI,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAC5C,QAAQ,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IACpD,QAAQ,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAKpD,OAAO,CAAC,cAAc,CAKpB;gBAEU,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;IA6BzD,MAAM,CAAC,MAAM,EAAE,iBAAiB;IAQhC,MAAM,CAAC,WAAW,EAAE,iBAAiB;IASrC,kBAAkB;IAQlB,MAAM;YAME,EAAE;CAUjB"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import createClient, {} from "openapi-fetch";
|
|
2
|
+
import { unwrap } from "./http.js";
|
|
3
|
+
export { ApiError } from "./http.js";
|
|
4
|
+
import { createProductsResource } from "./resources/products.js";
|
|
5
|
+
import { createCartResource } from "./resources/cart.js";
|
|
6
|
+
import { createCheckoutResource } from "./resources/checkout.js";
|
|
7
|
+
import { createCustomerResource } from "./resources/customer.js";
|
|
8
|
+
const APP_KEY_HEADER = "x-app-key";
|
|
9
|
+
export class StorefrontClient {
|
|
10
|
+
appKey;
|
|
11
|
+
// set automatically the first time cart.addItem() creates a cart — or
|
|
12
|
+
// pass one in up front (e.g. restored from localStorage) to resume a cart
|
|
13
|
+
cartToken;
|
|
14
|
+
// in-memory only, like merchant-sdk — a page refresh re-derives it from the
|
|
15
|
+
// httpOnly customer_refresh_token cookie via refreshAccessToken()
|
|
16
|
+
accessToken;
|
|
17
|
+
client;
|
|
18
|
+
products;
|
|
19
|
+
cart;
|
|
20
|
+
checkout;
|
|
21
|
+
customer;
|
|
22
|
+
// every authenticated request needs the bearer token and the cross-origin
|
|
23
|
+
// cookie (for customer_refresh_token) — centralized here instead of at
|
|
24
|
+
// each call site, same pattern as merchant-sdk's AdminClient
|
|
25
|
+
authMiddleware = {
|
|
26
|
+
onRequest: ({ request }) => {
|
|
27
|
+
request.headers.set("Authorization", `Bearer ${this.accessToken}`);
|
|
28
|
+
return new Request(request, { credentials: "include" });
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
constructor(baseUrl, appKey, cartToken) {
|
|
32
|
+
this.appKey = appKey;
|
|
33
|
+
this.cartToken = cartToken;
|
|
34
|
+
this.client = createClient({ baseUrl });
|
|
35
|
+
// the app key identifies the tenant on every request — read off `this`
|
|
36
|
+
// rather than captured at construction, so reassigning `appKey` later
|
|
37
|
+
// (e.g. switching storefronts) takes effect immediately
|
|
38
|
+
this.client.use({
|
|
39
|
+
onRequest: ({ request }) => {
|
|
40
|
+
request.headers.set(APP_KEY_HEADER, this.appKey);
|
|
41
|
+
return request;
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
this.client.use(this.authMiddleware);
|
|
45
|
+
const doRequest = (request) => this.do(request);
|
|
46
|
+
this.products = createProductsResource(this.client);
|
|
47
|
+
this.cart = createCartResource(this.client, () => this.cartToken, (token) => {
|
|
48
|
+
this.cartToken = token;
|
|
49
|
+
});
|
|
50
|
+
this.checkout = createCheckoutResource(this.client, () => this.cartToken);
|
|
51
|
+
this.customer = createCustomerResource(this.client, doRequest);
|
|
52
|
+
}
|
|
53
|
+
async signUp(signup) {
|
|
54
|
+
const result = await this.client.POST("/auth/signup", { body: signup });
|
|
55
|
+
this.accessToken = unwrap(result).access_token;
|
|
56
|
+
return this.accessToken;
|
|
57
|
+
}
|
|
58
|
+
// sends the current cart token (if any) so the backend can claim the
|
|
59
|
+
// guest cart into the newly-signed-in customer's account
|
|
60
|
+
async signIn(credentials) {
|
|
61
|
+
const result = await this.client.POST("/auth/signin", {
|
|
62
|
+
body: credentials,
|
|
63
|
+
headers: this.cartToken ? { "x-cart-token": this.cartToken } : {},
|
|
64
|
+
});
|
|
65
|
+
this.accessToken = unwrap(result).access_token;
|
|
66
|
+
return this.accessToken;
|
|
67
|
+
}
|
|
68
|
+
async refreshAccessToken() {
|
|
69
|
+
const { data } = await this.client.GET("/auth/token/refresh");
|
|
70
|
+
this.accessToken = data?.access_token;
|
|
71
|
+
return this.accessToken;
|
|
72
|
+
}
|
|
73
|
+
// clears the httpOnly customer_refresh_token cookie server-side — the
|
|
74
|
+
// client can't delete it itself — then drops the in-memory access token
|
|
75
|
+
async logout() {
|
|
76
|
+
await this.client.POST("/auth/logout");
|
|
77
|
+
this.accessToken = undefined;
|
|
78
|
+
}
|
|
79
|
+
// request is a thunk so the retry rebuilds headers off the refreshed accessToken, not a stale one
|
|
80
|
+
async do(request) {
|
|
81
|
+
const result = await request();
|
|
82
|
+
if (result.response.status === 401) {
|
|
83
|
+
await this.refreshAccessToken();
|
|
84
|
+
return await request();
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Client } from "openapi-fetch";
|
|
2
|
+
import type { components, paths } from "../types.gen.js";
|
|
3
|
+
export declare function createCartResource(client: Client<paths>, getCartToken: () => string | undefined, setCartToken: (token: string) => void): {
|
|
4
|
+
addItem: (body: components["schemas"]["AddCartItemDto"]) => Promise<{
|
|
5
|
+
token: string;
|
|
6
|
+
items: components["schemas"]["CartItem"][];
|
|
7
|
+
subtotalCents: number;
|
|
8
|
+
itemCount: number;
|
|
9
|
+
}>;
|
|
10
|
+
get: () => Promise<{
|
|
11
|
+
token: string;
|
|
12
|
+
items: {
|
|
13
|
+
variantId: number;
|
|
14
|
+
productId: number;
|
|
15
|
+
productName: string;
|
|
16
|
+
sku: string | null;
|
|
17
|
+
priceCents: number;
|
|
18
|
+
quantity: number;
|
|
19
|
+
stock: number;
|
|
20
|
+
optionValues: {
|
|
21
|
+
optionName: string;
|
|
22
|
+
value: string;
|
|
23
|
+
}[];
|
|
24
|
+
}[];
|
|
25
|
+
subtotalCents: number;
|
|
26
|
+
itemCount: number;
|
|
27
|
+
} | undefined>;
|
|
28
|
+
updateItem: (variantId: number, body: components["schemas"]["UpdateCartItemDto"]) => Promise<{
|
|
29
|
+
token: string;
|
|
30
|
+
items: {
|
|
31
|
+
variantId: number;
|
|
32
|
+
productId: number;
|
|
33
|
+
productName: string;
|
|
34
|
+
sku: string | null;
|
|
35
|
+
priceCents: number;
|
|
36
|
+
quantity: number;
|
|
37
|
+
stock: number;
|
|
38
|
+
optionValues: {
|
|
39
|
+
optionName: string;
|
|
40
|
+
value: string;
|
|
41
|
+
}[];
|
|
42
|
+
}[];
|
|
43
|
+
subtotalCents: number;
|
|
44
|
+
itemCount: number;
|
|
45
|
+
}>;
|
|
46
|
+
removeItem: (variantId: number) => Promise<{
|
|
47
|
+
token: string;
|
|
48
|
+
items: {
|
|
49
|
+
variantId: number;
|
|
50
|
+
productId: number;
|
|
51
|
+
productName: string;
|
|
52
|
+
sku: string | null;
|
|
53
|
+
priceCents: number;
|
|
54
|
+
quantity: number;
|
|
55
|
+
stock: number;
|
|
56
|
+
optionValues: {
|
|
57
|
+
optionName: string;
|
|
58
|
+
value: string;
|
|
59
|
+
}[];
|
|
60
|
+
}[];
|
|
61
|
+
subtotalCents: number;
|
|
62
|
+
itemCount: number;
|
|
63
|
+
}>;
|
|
64
|
+
clear: () => Promise<{
|
|
65
|
+
token: string;
|
|
66
|
+
items: {
|
|
67
|
+
variantId: number;
|
|
68
|
+
productId: number;
|
|
69
|
+
productName: string;
|
|
70
|
+
sku: string | null;
|
|
71
|
+
priceCents: number;
|
|
72
|
+
quantity: number;
|
|
73
|
+
stock: number;
|
|
74
|
+
optionValues: {
|
|
75
|
+
optionName: string;
|
|
76
|
+
value: string;
|
|
77
|
+
}[];
|
|
78
|
+
}[];
|
|
79
|
+
subtotalCents: number;
|
|
80
|
+
itemCount: number;
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=cart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart.d.ts","sourceRoot":"","sources":["../../src/resources/cart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAKzD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EACrB,YAAY,EAAE,MAAM,MAAM,GAAG,SAAS,EACtC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;oBAoBb,UAAU,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC;;eA2CmrN,qBAAsB;;;;;;;;;;;;;;;;;;;;;;4BA7BzvN,MAAM,QACX,UAAU,CAAC,SAAS,CAAC,CAAC,mBAAmB,CAAC;;;;;;;;;;;;;;;;;;4BAYpB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAevC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { unwrap } from "../http.js";
|
|
2
|
+
const CART_TOKEN_HEADER = "x-cart-token";
|
|
3
|
+
export function createCartResource(client, getCartToken, setCartToken) {
|
|
4
|
+
// x-cart-token isn't a documented OpenAPI header parameter (it's read via
|
|
5
|
+
// a plain decorator server-side, not @ApiHeader), so it's sent as a raw
|
|
6
|
+
// fetch header rather than through the typed params.header slot
|
|
7
|
+
function cartHeaders() {
|
|
8
|
+
const token = getCartToken();
|
|
9
|
+
return token ? { [CART_TOKEN_HEADER]: token } : {};
|
|
10
|
+
}
|
|
11
|
+
// addItem may create a cart server-side and hand back a new token — this
|
|
12
|
+
// captures it so the caller doesn't have to wire that up by hand. addItem
|
|
13
|
+
// always calls this with unwrap()'s result, which is defined or throws —
|
|
14
|
+
// never undefined — so this stays non-optional rather than re-widening it.
|
|
15
|
+
function captureToken(cart) {
|
|
16
|
+
setCartToken(cart.token);
|
|
17
|
+
return cart;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
addItem: async (body) => {
|
|
21
|
+
const result = await client.POST("/cart/items", {
|
|
22
|
+
body,
|
|
23
|
+
headers: cartHeaders(),
|
|
24
|
+
});
|
|
25
|
+
return captureToken(unwrap(result));
|
|
26
|
+
},
|
|
27
|
+
get: async () => {
|
|
28
|
+
const { data } = await client.GET("/cart", { headers: cartHeaders() });
|
|
29
|
+
return data;
|
|
30
|
+
},
|
|
31
|
+
updateItem: async (variantId, body) => {
|
|
32
|
+
const path = { variantId: String(variantId) };
|
|
33
|
+
const result = await client.PATCH("/cart/items/{variantId}", {
|
|
34
|
+
params: { path },
|
|
35
|
+
body,
|
|
36
|
+
headers: cartHeaders(),
|
|
37
|
+
});
|
|
38
|
+
return unwrap(result);
|
|
39
|
+
},
|
|
40
|
+
removeItem: async (variantId) => {
|
|
41
|
+
const path = { variantId: String(variantId) };
|
|
42
|
+
const result = await client.DELETE("/cart/items/{variantId}", {
|
|
43
|
+
params: { path },
|
|
44
|
+
headers: cartHeaders(),
|
|
45
|
+
});
|
|
46
|
+
return unwrap(result);
|
|
47
|
+
},
|
|
48
|
+
clear: async () => {
|
|
49
|
+
const result = await client.DELETE("/cart", { headers: cartHeaders() });
|
|
50
|
+
return unwrap(result);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=cart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart.js","sourceRoot":"","sources":["../../src/resources/cart.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC,MAAM,UAAU,kBAAkB,CAChC,MAAqB,EACrB,YAAsC,EACtC,YAAqC;IAErC,0EAA0E;IAC1E,wEAAwE;IACxE,gEAAgE;IAChE,SAAS,WAAW;QAClB,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,CAAC;IAED,yEAAyE;IACzE,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,SAAS,YAAY,CAAC,IAAmC;QACvD,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,IAA6C,EAAE,EAAE;YAC/D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE;gBAC9C,IAAI;gBACJ,OAAO,EAAE,WAAW,EAAE;aACvB,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACtC,CAAC;QAED,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,UAAU,EAAE,KAAK,EACf,SAAiB,EACjB,IAAgD,EAChD,EAAE;YACF,MAAM,IAAI,GACR,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE;gBAC3D,MAAM,EAAE,EAAE,IAAI,EAAE;gBAChB,IAAI;gBACJ,OAAO,EAAE,WAAW,EAAE;aACvB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,UAAU,EAAE,KAAK,EAAE,SAAiB,EAAE,EAAE;YACtC,MAAM,IAAI,GACR,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,yBAAyB,EAAE;gBAC5D,MAAM,EAAE,EAAE,IAAI,EAAE;gBAChB,OAAO,EAAE,WAAW,EAAE;aACvB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;YACxE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Client } from "openapi-fetch";
|
|
2
|
+
import type { components, paths } from "../types.gen.js";
|
|
3
|
+
export declare function createCheckoutResource(client: Client<paths>, getCartToken: () => string | undefined): {
|
|
4
|
+
getConfig: () => Promise<{
|
|
5
|
+
ready: boolean;
|
|
6
|
+
stripeAccountId: string | null;
|
|
7
|
+
} | undefined>;
|
|
8
|
+
createSession: (body: components["schemas"]["CreateCheckoutSessionDto"]) => Promise<{
|
|
9
|
+
clientSecret: string;
|
|
10
|
+
}>;
|
|
11
|
+
getSessionStatus: (sessionId: string) => Promise<{
|
|
12
|
+
status: string;
|
|
13
|
+
paymentStatus: string;
|
|
14
|
+
customerEmail: string | null;
|
|
15
|
+
} | undefined>;
|
|
16
|
+
getShippingOptions: (body: components["schemas"]["GetShippingOptionsDto"]) => Promise<{
|
|
17
|
+
ok: boolean;
|
|
18
|
+
errorMessage?: string;
|
|
19
|
+
} | undefined>;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=checkout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/resources/checkout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAKzD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EACrB,YAAY,EAAE,MAAM,MAAM,GAAG,SAAS;;;;;0BAaR,UAAU,CAAC,SAAS,CAAC,CAAC,0BAA0B,CAAC;;;kCAQzC,MAAM;;;;;+BAUlC,UAAU,CAAC,SAAS,CAAC,CAAC,uBAAuB,CAAC;;;;EAMzD"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { unwrap } from "../http.js";
|
|
2
|
+
const CART_TOKEN_HEADER = "x-cart-token";
|
|
3
|
+
export function createCheckoutResource(client, getCartToken) {
|
|
4
|
+
function cartHeaders() {
|
|
5
|
+
const token = getCartToken();
|
|
6
|
+
return token ? { [CART_TOKEN_HEADER]: token } : {};
|
|
7
|
+
}
|
|
8
|
+
return {
|
|
9
|
+
getConfig: async () => {
|
|
10
|
+
const { data } = await client.GET("/checkout/config");
|
|
11
|
+
return data;
|
|
12
|
+
},
|
|
13
|
+
createSession: async (body) => {
|
|
14
|
+
const result = await client.POST("/checkout/session", {
|
|
15
|
+
body,
|
|
16
|
+
headers: cartHeaders(),
|
|
17
|
+
});
|
|
18
|
+
return unwrap(result);
|
|
19
|
+
},
|
|
20
|
+
getSessionStatus: async (sessionId) => {
|
|
21
|
+
const path = { sessionId };
|
|
22
|
+
const { data } = await client.GET("/checkout/session/{sessionId}", {
|
|
23
|
+
params: { path },
|
|
24
|
+
});
|
|
25
|
+
return data;
|
|
26
|
+
},
|
|
27
|
+
getShippingOptions: async (body) => {
|
|
28
|
+
const { data } = await client.POST("/checkout/shipping-options", { body });
|
|
29
|
+
return data;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=checkout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/resources/checkout.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC,MAAM,UAAU,sBAAsB,CACpC,MAAqB,EACrB,YAAsC;IAEtC,SAAS,WAAW;QAClB,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,CAAC;IAED,OAAO;QACL,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,aAAa,EAAE,KAAK,EAAE,IAAuD,EAAE,EAAE;YAC/E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE;gBACpD,IAAI;gBACJ,OAAO,EAAE,WAAW,EAAE;aACvB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,gBAAgB,EAAE,KAAK,EAAE,SAAiB,EAAE,EAAE;YAC5C,MAAM,IAAI,GACR,EAAE,SAAS,EAAE,CAAC;YAChB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,+BAA+B,EAAE;gBACjE,MAAM,EAAE,EAAE,IAAI,EAAE;aACjB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB,EAAE,KAAK,EACvB,IAAoD,EACpD,EAAE;YACF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3E,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Client } from "openapi-fetch";
|
|
2
|
+
import type { components, paths } from "../types.gen.js";
|
|
3
|
+
import { type DoFn } from "../http.js";
|
|
4
|
+
export declare function createCustomerResource(client: Client<paths>, doRequest: DoFn): {
|
|
5
|
+
get: () => Promise<{
|
|
6
|
+
id: number;
|
|
7
|
+
accountId: number;
|
|
8
|
+
firstName: string;
|
|
9
|
+
lastName: string;
|
|
10
|
+
email: string;
|
|
11
|
+
createdAt: string;
|
|
12
|
+
updatedAt: string;
|
|
13
|
+
} | undefined>;
|
|
14
|
+
update: (params: components["schemas"]["UpdateCustomerDto"]) => Promise<{
|
|
15
|
+
id: number;
|
|
16
|
+
accountId: number;
|
|
17
|
+
firstName: string;
|
|
18
|
+
lastName: string;
|
|
19
|
+
email: string;
|
|
20
|
+
createdAt: string;
|
|
21
|
+
updatedAt: string;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=customer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customer.d.ts","sourceRoot":"","sources":["../../src/resources/customer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAU,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI;;;;;;;;;;qBAOlD,UAAU,CAAC,SAAS,CAAC,CAAC,mBAAmB,CAAC;;;;;;;;;EAOpE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { unwrap } from "../http.js";
|
|
2
|
+
export function createCustomerResource(client, doRequest) {
|
|
3
|
+
return {
|
|
4
|
+
get: async () => {
|
|
5
|
+
const { data } = await doRequest(() => client.GET("/customer"));
|
|
6
|
+
return data;
|
|
7
|
+
},
|
|
8
|
+
update: async (params) => {
|
|
9
|
+
const result = await doRequest(() => client.PATCH("/customer", { body: params }));
|
|
10
|
+
return unwrap(result);
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=customer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customer.js","sourceRoot":"","sources":["../../src/resources/customer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAa,MAAM,YAAY,CAAC;AAE/C,MAAM,UAAU,sBAAsB,CAAC,MAAqB,EAAE,SAAe;IAC3E,OAAO;QACL,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,MAAkD,EAAE,EAAE;YACnE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAClC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAC5C,CAAC;YACF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Client } from "openapi-fetch";
|
|
2
|
+
import type { paths } from "../types.gen.js";
|
|
3
|
+
export declare function createProductsResource(client: Client<paths>): {
|
|
4
|
+
list: (query?: paths["/products"]["get"]["parameters"]["query"]) => Promise<{
|
|
5
|
+
items: {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
description: string | null;
|
|
9
|
+
brand: {
|
|
10
|
+
id: number;
|
|
11
|
+
name: string;
|
|
12
|
+
} | null;
|
|
13
|
+
categories: {
|
|
14
|
+
id: number;
|
|
15
|
+
name: string;
|
|
16
|
+
}[];
|
|
17
|
+
minPriceCents: number | null;
|
|
18
|
+
maxPriceCents: number | null;
|
|
19
|
+
thumbnailUrl: string | null;
|
|
20
|
+
}[];
|
|
21
|
+
total: number;
|
|
22
|
+
limit: number;
|
|
23
|
+
offset: number;
|
|
24
|
+
} | undefined>;
|
|
25
|
+
getById: (id: number) => Promise<{
|
|
26
|
+
id: number;
|
|
27
|
+
name: string;
|
|
28
|
+
description: string | null;
|
|
29
|
+
brand: {
|
|
30
|
+
id: number;
|
|
31
|
+
name: string;
|
|
32
|
+
} | null;
|
|
33
|
+
categories: {
|
|
34
|
+
id: number;
|
|
35
|
+
name: string;
|
|
36
|
+
}[];
|
|
37
|
+
options: {
|
|
38
|
+
id: number;
|
|
39
|
+
name: string;
|
|
40
|
+
values: {
|
|
41
|
+
id: number;
|
|
42
|
+
value: string;
|
|
43
|
+
}[];
|
|
44
|
+
}[];
|
|
45
|
+
variants: {
|
|
46
|
+
id: number;
|
|
47
|
+
sku: string | null;
|
|
48
|
+
priceCents: number;
|
|
49
|
+
stock: number;
|
|
50
|
+
optionValues: {
|
|
51
|
+
optionName: string;
|
|
52
|
+
value: string;
|
|
53
|
+
}[];
|
|
54
|
+
images: {
|
|
55
|
+
id: number;
|
|
56
|
+
url: string;
|
|
57
|
+
position: number;
|
|
58
|
+
}[];
|
|
59
|
+
}[];
|
|
60
|
+
images: {
|
|
61
|
+
id: number;
|
|
62
|
+
url: string;
|
|
63
|
+
position: number;
|
|
64
|
+
}[];
|
|
65
|
+
} | undefined>;
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=products.d.ts.map
|