@doswiftly/storefront-sdk 10.0.0 → 11.0.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/CHANGELOG.md +24 -0
- package/dist/core/cart/cart-client.d.ts +17 -15
- package/dist/core/cart/cart-client.d.ts.map +1 -1
- package/dist/core/cart/cart-client.js +10 -11
- package/dist/core/operations/auth.d.ts +5 -5
- package/dist/core/operations/auth.d.ts.map +1 -1
- package/dist/core/operations/auth.js +11 -10
- package/dist/core/operations/cart.d.ts +24 -24
- package/dist/core/operations/cart.d.ts.map +1 -1
- package/dist/core/operations/cart.js +42 -43
- package/dist/core/operations/compose.d.ts +24 -0
- package/dist/core/operations/compose.d.ts.map +1 -0
- package/dist/core/operations/compose.js +58 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 11.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- c1faee7: **Breaking:** `cartComplete` no longer returns `cart` in its payload.
|
|
8
|
+
|
|
9
|
+
After completion the cart is converted and locked — returning it meant an extra server round-trip for a dead resource. The mutation payload (and `cartClient.complete()`) now returns only `{ order, warnings }`. The `order` is the meaningful result of completion and carries `canCreatePayment` + `paymentMethodType` for the post-completion payment flow.
|
|
10
|
+
|
|
11
|
+
**Migration:**
|
|
12
|
+
- `cartClient.complete()` now returns `{ order, warnings }` — remove any use of `result.cart`. After completion, clear your local cart state and work with `result.order`.
|
|
13
|
+
- If you query `cartComplete` directly, drop the `cart { ... }` selection — the field no longer exists on `CartCompletePayload`.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 363fa74: Fix `cartClient.complete()` failing with HTTP 400 `There can be only one fragment named "Money"`.
|
|
18
|
+
|
|
19
|
+
The `cartComplete` operation selects both `cart` and `order`, whose GraphQL fragment trees share nested fragments (`Money`, `MailingAddress`). The operation string emitted those shared fragments twice — an invalid GraphQL document that the server rejects, so `cartClient.complete()` failed before an order could be submitted.
|
|
20
|
+
|
|
21
|
+
**Detailed changes:**
|
|
22
|
+
- Every cart and customer operation is now assembled through a fragment-deduplicating composer, so a fragment shared across selections is emitted exactly once. No API surface change — the operations behave identically, they are just valid documents now.
|
|
23
|
+
- `CartCompleteOutcome.order` is now `Order` (non-null) instead of `Order | null`. On a successful `complete()` the created order is always present in the result — `complete()` already throws on `userErrors` before returning, so there is no success path with a missing order. Existing `if (result.order)` checks keep compiling.
|
|
24
|
+
|
|
25
|
+
**Migration:** none required. If you added a workaround that re-fetched the order when `complete()` returned `order: null`, you can drop it — `result.order` is now always populated on success.
|
|
26
|
+
|
|
3
27
|
## 10.0.0
|
|
4
28
|
|
|
5
29
|
### Major Changes
|
|
@@ -32,13 +32,15 @@ export interface CartMutationOutcome {
|
|
|
32
32
|
warnings: CartWarning[];
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* cartComplete result — `order`
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* cartComplete result — `order` is the Order created from the cart, non-null on
|
|
36
|
+
* success (`complete()` throws via `assertNoUserErrors` before returning if the
|
|
37
|
+
* mutation reported `userErrors`). The cart is NOT returned: after completion it
|
|
38
|
+
* is CONVERTED/locked, so drop your local cart and work with the Order. The
|
|
39
|
+
* Order carries `canCreatePayment` + `paymentMethodType` for deciding the
|
|
40
|
+
* post-completion payment flow.
|
|
38
41
|
*/
|
|
39
42
|
export interface CartCompleteOutcome {
|
|
40
|
-
|
|
41
|
-
order: Order | null;
|
|
43
|
+
order: Order;
|
|
42
44
|
warnings: CartWarning[];
|
|
43
45
|
}
|
|
44
46
|
export declare class CartClient {
|
|
@@ -115,17 +117,17 @@ export declare class CartClient {
|
|
|
115
117
|
*/
|
|
116
118
|
updateGiftCardRecipient(input: CartUpdateGiftCardRecipientInput): Promise<CartMutationOutcome>;
|
|
117
119
|
/**
|
|
118
|
-
* Complete cart → create Order. Returns `{
|
|
119
|
-
* Idempotent on `idempotencyKey` (auto-generated
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* Order zawiera `canCreatePayment` + `paymentMethodType` (po extend fragment
|
|
123
|
-
* Order w SSOT) — storefront czyta żeby zdecydować payment flow. paymentUrl
|
|
124
|
-
* celowo NIE w response (Decision D4) — storefront inicjuje payment osobnym
|
|
125
|
-
* `paymentCreate` mutation (po sprawdzeniu order.canCreatePayment).
|
|
120
|
+
* Complete cart → create Order. Returns `{ order, warnings }`.
|
|
121
|
+
* Idempotent on `idempotencyKey` (auto-generated from cartId + minute timestamp
|
|
122
|
+
* if omitted).
|
|
126
123
|
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
124
|
+
* `order` is populated on success — `assertNoUserErrors` throws first if the
|
|
125
|
+
* mutation reported `userErrors`. The cart is NOT returned: after completion it
|
|
126
|
+
* is CONVERTED/locked, so drop your local cart and work with the Order. The
|
|
127
|
+
* Order carries `canCreatePayment` + `paymentMethodType` so the storefront can
|
|
128
|
+
* decide the payment flow. `paymentUrl` is intentionally NOT in the response
|
|
129
|
+
* (Decision D4) — the storefront initiates payment with a separate
|
|
130
|
+
* `paymentCreate` mutation after checking `order.canCreatePayment`.
|
|
129
131
|
*/
|
|
130
132
|
complete(input: CartCompleteInput): Promise<CartCompleteOutcome>;
|
|
131
133
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cart-client.d.ts","sourceRoot":"","sources":["../../../src/core/cart/cart-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EACV,IAAI,EACJ,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,wBAAwB,EACzB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"cart-client.d.ts","sourceRoot":"","sources":["../../../src/core/cart/cart-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EACV,IAAI,EACJ,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,wBAAwB,EACzB,MAAM,SAAS,CAAC;AA8CjB;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IAErD;;;OAGG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAQ/C;;OAEG;IACG,MAAM,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASnE;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASpF;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS7F;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASlF;;;OAGG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAShG;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS5E;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAa9G;;;OAGG;IACG,kBAAkB,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS1F;;;OAGG;IACG,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASxF;;;OAGG;IACG,oBAAoB,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS9F;;;OAGG;IACG,mBAAmB,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS5F;;;OAGG;IACG,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAShF;;;OAGG;IACG,cAAc,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASlF;;;;OAIG;IACG,uBAAuB,CAAC,KAAK,EAAE,gCAAgC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASpG;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAYtE;;;;;;;;OAQG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAOpG"}
|
|
@@ -161,23 +161,22 @@ export class CartClient {
|
|
|
161
161
|
return { cart: data.cartUpdateGiftCardRecipient.cart, warnings: data.cartUpdateGiftCardRecipient.warnings ?? [] };
|
|
162
162
|
}
|
|
163
163
|
/**
|
|
164
|
-
* Complete cart → create Order. Returns `{
|
|
165
|
-
* Idempotent on `idempotencyKey` (auto-generated
|
|
166
|
-
*
|
|
164
|
+
* Complete cart → create Order. Returns `{ order, warnings }`.
|
|
165
|
+
* Idempotent on `idempotencyKey` (auto-generated from cartId + minute timestamp
|
|
166
|
+
* if omitted).
|
|
167
167
|
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* `
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
168
|
+
* `order` is populated on success — `assertNoUserErrors` throws first if the
|
|
169
|
+
* mutation reported `userErrors`. The cart is NOT returned: after completion it
|
|
170
|
+
* is CONVERTED/locked, so drop your local cart and work with the Order. The
|
|
171
|
+
* Order carries `canCreatePayment` + `paymentMethodType` so the storefront can
|
|
172
|
+
* decide the payment flow. `paymentUrl` is intentionally NOT in the response
|
|
173
|
+
* (Decision D4) — the storefront initiates payment with a separate
|
|
174
|
+
* `paymentCreate` mutation after checking `order.canCreatePayment`.
|
|
175
175
|
*/
|
|
176
176
|
async complete(input) {
|
|
177
177
|
const data = await this.client.mutate(CART_COMPLETE, { input });
|
|
178
178
|
assertNoUserErrors(data.cartComplete);
|
|
179
179
|
return {
|
|
180
|
-
cart: data.cartComplete.cart,
|
|
181
180
|
order: data.cartComplete.order,
|
|
182
181
|
warnings: data.cartComplete.warnings ?? [],
|
|
183
182
|
};
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
* - customerRefreshToken → CustomerRefreshTokenPayload
|
|
10
10
|
* - customerSignup(input: CustomerCreateInput!) → CustomerSignupPayload
|
|
11
11
|
*/
|
|
12
|
-
export declare const CUSTOMER_LOGIN
|
|
13
|
-
export declare const CUSTOMER_LOGOUT
|
|
14
|
-
export declare const CUSTOMER_REFRESH_TOKEN
|
|
15
|
-
export declare const CUSTOMER_SIGNUP
|
|
16
|
-
export declare const CUSTOMER_QUERY
|
|
12
|
+
export declare const CUSTOMER_LOGIN: string;
|
|
13
|
+
export declare const CUSTOMER_LOGOUT: string;
|
|
14
|
+
export declare const CUSTOMER_REFRESH_TOKEN: string;
|
|
15
|
+
export declare const CUSTOMER_SIGNUP: string;
|
|
16
|
+
export declare const CUSTOMER_QUERY: string;
|
|
17
17
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/core/operations/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/core/operations/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgEH,eAAO,MAAM,cAAc,QASzB,CAAC;AAEH,eAAO,MAAM,eAAe,QAS1B,CAAC;AAEH,eAAO,MAAM,sBAAsB,QASjC,CAAC;AAEH,eAAO,MAAM,eAAe,QAW1B,CAAC;AAMH,eAAO,MAAM,cAAc,QAOzB,CAAC"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - customerRefreshToken → CustomerRefreshTokenPayload
|
|
10
10
|
* - customerSignup(input: CustomerCreateInput!) → CustomerSignupPayload
|
|
11
11
|
*/
|
|
12
|
+
import { composeOperation } from './compose';
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
13
14
|
// Fragments
|
|
14
15
|
// ---------------------------------------------------------------------------
|
|
@@ -64,7 +65,7 @@ const CUSTOMER_FRAGMENT = `
|
|
|
64
65
|
// ---------------------------------------------------------------------------
|
|
65
66
|
// Mutations
|
|
66
67
|
// ---------------------------------------------------------------------------
|
|
67
|
-
export const CUSTOMER_LOGIN = `
|
|
68
|
+
export const CUSTOMER_LOGIN = composeOperation(`
|
|
68
69
|
mutation CustomerLogin($input: CustomerAccessTokenCreateInput!) {
|
|
69
70
|
customerLogin(input: $input) {
|
|
70
71
|
customerAccessToken { ...CustomerAccessTokenFields }
|
|
@@ -73,8 +74,8 @@ export const CUSTOMER_LOGIN = `
|
|
|
73
74
|
}
|
|
74
75
|
${CUSTOMER_ACCESS_TOKEN_FRAGMENT}
|
|
75
76
|
${USER_ERROR_FRAGMENT}
|
|
76
|
-
|
|
77
|
-
export const CUSTOMER_LOGOUT = `
|
|
77
|
+
`);
|
|
78
|
+
export const CUSTOMER_LOGOUT = composeOperation(`
|
|
78
79
|
mutation CustomerLogout {
|
|
79
80
|
customerLogout {
|
|
80
81
|
deletedAccessToken
|
|
@@ -83,8 +84,8 @@ export const CUSTOMER_LOGOUT = `
|
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
${USER_ERROR_FRAGMENT}
|
|
86
|
-
|
|
87
|
-
export const CUSTOMER_REFRESH_TOKEN = `
|
|
87
|
+
`);
|
|
88
|
+
export const CUSTOMER_REFRESH_TOKEN = composeOperation(`
|
|
88
89
|
mutation CustomerRefreshToken {
|
|
89
90
|
customerRefreshToken {
|
|
90
91
|
customerAccessToken { ...CustomerAccessTokenFields }
|
|
@@ -93,8 +94,8 @@ export const CUSTOMER_REFRESH_TOKEN = `
|
|
|
93
94
|
}
|
|
94
95
|
${CUSTOMER_ACCESS_TOKEN_FRAGMENT}
|
|
95
96
|
${USER_ERROR_FRAGMENT}
|
|
96
|
-
|
|
97
|
-
export const CUSTOMER_SIGNUP = `
|
|
97
|
+
`);
|
|
98
|
+
export const CUSTOMER_SIGNUP = composeOperation(`
|
|
98
99
|
mutation CustomerSignup($input: CustomerCreateInput!) {
|
|
99
100
|
customerSignup(input: $input) {
|
|
100
101
|
customer { ...CustomerFields }
|
|
@@ -105,15 +106,15 @@ export const CUSTOMER_SIGNUP = `
|
|
|
105
106
|
${CUSTOMER_FRAGMENT}
|
|
106
107
|
${CUSTOMER_ACCESS_TOKEN_FRAGMENT}
|
|
107
108
|
${USER_ERROR_FRAGMENT}
|
|
108
|
-
|
|
109
|
+
`);
|
|
109
110
|
// ---------------------------------------------------------------------------
|
|
110
111
|
// Queries
|
|
111
112
|
// ---------------------------------------------------------------------------
|
|
112
|
-
export const CUSTOMER_QUERY = `
|
|
113
|
+
export const CUSTOMER_QUERY = composeOperation(`
|
|
113
114
|
query Customer {
|
|
114
115
|
customer {
|
|
115
116
|
...CustomerFields
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
${CUSTOMER_FRAGMENT}
|
|
119
|
-
|
|
120
|
+
`);
|
|
@@ -11,31 +11,31 @@
|
|
|
11
11
|
* Cart mutations always return full Cart + userErrors + warnings (non-fatal hints).
|
|
12
12
|
* Drift detection: PreToolUse hook validuje strings przeciwko storefront-operations/schema.graphql.
|
|
13
13
|
*/
|
|
14
|
-
export declare const CART_QUERY
|
|
15
|
-
export declare const CART_CREATE
|
|
16
|
-
export declare const CART_ADD_LINES
|
|
17
|
-
export declare const CART_UPDATE_LINES
|
|
18
|
-
export declare const CART_REMOVE_LINES
|
|
19
|
-
export declare const CART_DISCOUNT_CODES_UPDATE
|
|
20
|
-
export declare const CART_UPDATE_NOTE
|
|
21
|
-
export declare const CART_UPDATE_BUYER_IDENTITY
|
|
22
|
-
export declare const CART_SET_SHIPPING_ADDRESS
|
|
23
|
-
export declare const CART_SET_BILLING_ADDRESS
|
|
24
|
-
export declare const CART_SELECT_SHIPPING_METHOD
|
|
25
|
-
export declare const CART_SELECT_PAYMENT_METHOD
|
|
26
|
-
export declare const CART_APPLY_GIFT_CARD
|
|
27
|
-
export declare const CART_REMOVE_GIFT_CARD
|
|
28
|
-
export declare const CART_UPDATE_GIFT_CARD_RECIPIENT
|
|
14
|
+
export declare const CART_QUERY: string;
|
|
15
|
+
export declare const CART_CREATE: string;
|
|
16
|
+
export declare const CART_ADD_LINES: string;
|
|
17
|
+
export declare const CART_UPDATE_LINES: string;
|
|
18
|
+
export declare const CART_REMOVE_LINES: string;
|
|
19
|
+
export declare const CART_DISCOUNT_CODES_UPDATE: string;
|
|
20
|
+
export declare const CART_UPDATE_NOTE: string;
|
|
21
|
+
export declare const CART_UPDATE_BUYER_IDENTITY: string;
|
|
22
|
+
export declare const CART_SET_SHIPPING_ADDRESS: string;
|
|
23
|
+
export declare const CART_SET_BILLING_ADDRESS: string;
|
|
24
|
+
export declare const CART_SELECT_SHIPPING_METHOD: string;
|
|
25
|
+
export declare const CART_SELECT_PAYMENT_METHOD: string;
|
|
26
|
+
export declare const CART_APPLY_GIFT_CARD: string;
|
|
27
|
+
export declare const CART_REMOVE_GIFT_CARD: string;
|
|
28
|
+
export declare const CART_UPDATE_GIFT_CARD_RECIPIENT: string;
|
|
29
29
|
/**
|
|
30
|
-
* cartComplete — returns
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
30
|
+
* cartComplete — returns the Order created from the cart (carrying
|
|
31
|
+
* `canCreatePayment` + `paymentMethodType` signals for post-completion payment
|
|
32
|
+
* flow decisions). The cart itself is NOT returned — after completion it is
|
|
33
|
+
* CONVERTED/locked, so the storefront drops its local cart and works with the
|
|
34
|
+
* Order. `order` is non-null on success. `paymentUrl` is intentionally NOT in
|
|
35
|
+
* the payload (Decision D4) — the storefront calls a separate `paymentCreate`
|
|
36
|
+
* mutation after checking `order.canCreatePayment`.
|
|
37
37
|
*/
|
|
38
|
-
export declare const CART_COMPLETE
|
|
38
|
+
export declare const CART_COMPLETE: string;
|
|
39
39
|
/**
|
|
40
40
|
* cartValidateDiscountCode Query — read-only preview discount applicability
|
|
41
41
|
* (Decision D3). No cart side effects; storefront UI używa do inline feedback
|
|
@@ -44,5 +44,5 @@ export declare const CART_COMPLETE = "\n mutation CartComplete($input: CartComp
|
|
|
44
44
|
* Caching guidance: `fetchPolicy: 'network-only'` lub key zawierający
|
|
45
45
|
* `cart.subtotal` (discount eligibility może zależeć od minimum order amount).
|
|
46
46
|
*/
|
|
47
|
-
export declare const CART_VALIDATE_DISCOUNT_CODE
|
|
47
|
+
export declare const CART_VALIDATE_DISCOUNT_CODE: string;
|
|
48
48
|
//# sourceMappingURL=cart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cart.d.ts","sourceRoot":"","sources":["../../../src/core/operations/cart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"cart.d.ts","sourceRoot":"","sources":["../../../src/core/operations/cart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA0RH,eAAO,MAAM,UAAU,QAOrB,CAAC;AAMH,eAAO,MAAM,WAAW,QAWtB,CAAC;AAEH,eAAO,MAAM,cAAc,QAWzB,CAAC;AAEH,eAAO,MAAM,iBAAiB,QAW5B,CAAC;AAEH,eAAO,MAAM,iBAAiB,QAW5B,CAAC;AAEH,eAAO,MAAM,0BAA0B,QAWrC,CAAC;AAEH,eAAO,MAAM,gBAAgB,QAW3B,CAAC;AAEH,eAAO,MAAM,0BAA0B,QAWrC,CAAC;AAMH,eAAO,MAAM,yBAAyB,QAWpC,CAAC;AAEH,eAAO,MAAM,wBAAwB,QAWnC,CAAC;AAEH,eAAO,MAAM,2BAA2B,QAWtC,CAAC;AAEH,eAAO,MAAM,0BAA0B,QAWrC,CAAC;AAEH,eAAO,MAAM,oBAAoB,QAW/B,CAAC;AAEH,eAAO,MAAM,qBAAqB,QAWhC,CAAC;AAEH,eAAO,MAAM,+BAA+B,QAW1C,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,QAWxB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,QAoBtC,CAAC"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* Cart mutations always return full Cart + userErrors + warnings (non-fatal hints).
|
|
12
12
|
* Drift detection: PreToolUse hook validuje strings przeciwko storefront-operations/schema.graphql.
|
|
13
13
|
*/
|
|
14
|
+
import { composeOperation } from './compose';
|
|
14
15
|
// ---------------------------------------------------------------------------
|
|
15
16
|
// Shared fragments (matching SSOT fragments.graphql)
|
|
16
17
|
// ---------------------------------------------------------------------------
|
|
@@ -266,18 +267,18 @@ const CART_WARNING_FRAGMENT = `
|
|
|
266
267
|
// ---------------------------------------------------------------------------
|
|
267
268
|
// Queries
|
|
268
269
|
// ---------------------------------------------------------------------------
|
|
269
|
-
export const CART_QUERY = `
|
|
270
|
+
export const CART_QUERY = composeOperation(`
|
|
270
271
|
query Cart($id: ID!) {
|
|
271
272
|
cart(id: $id) {
|
|
272
273
|
...Cart
|
|
273
274
|
}
|
|
274
275
|
}
|
|
275
276
|
${CART_FRAGMENT}
|
|
276
|
-
|
|
277
|
+
`);
|
|
277
278
|
// ---------------------------------------------------------------------------
|
|
278
279
|
// Mutations
|
|
279
280
|
// ---------------------------------------------------------------------------
|
|
280
|
-
export const CART_CREATE = `
|
|
281
|
+
export const CART_CREATE = composeOperation(`
|
|
281
282
|
mutation CartCreate($input: CartCreateInput) {
|
|
282
283
|
cartCreate(input: $input) {
|
|
283
284
|
cart { ...Cart }
|
|
@@ -288,8 +289,8 @@ export const CART_CREATE = `
|
|
|
288
289
|
${CART_FRAGMENT}
|
|
289
290
|
${USER_ERROR_FRAGMENT}
|
|
290
291
|
${CART_WARNING_FRAGMENT}
|
|
291
|
-
|
|
292
|
-
export const CART_ADD_LINES = `
|
|
292
|
+
`);
|
|
293
|
+
export const CART_ADD_LINES = composeOperation(`
|
|
293
294
|
mutation CartAddLines($id: ID!, $lines: [CartLineInput!]!) {
|
|
294
295
|
cartAddLines(id: $id, lines: $lines) {
|
|
295
296
|
cart { ...Cart }
|
|
@@ -300,8 +301,8 @@ export const CART_ADD_LINES = `
|
|
|
300
301
|
${CART_FRAGMENT}
|
|
301
302
|
${USER_ERROR_FRAGMENT}
|
|
302
303
|
${CART_WARNING_FRAGMENT}
|
|
303
|
-
|
|
304
|
-
export const CART_UPDATE_LINES = `
|
|
304
|
+
`);
|
|
305
|
+
export const CART_UPDATE_LINES = composeOperation(`
|
|
305
306
|
mutation CartUpdateLines($id: ID!, $lines: [CartLineUpdateInput!]!) {
|
|
306
307
|
cartUpdateLines(id: $id, lines: $lines) {
|
|
307
308
|
cart { ...Cart }
|
|
@@ -312,8 +313,8 @@ export const CART_UPDATE_LINES = `
|
|
|
312
313
|
${CART_FRAGMENT}
|
|
313
314
|
${USER_ERROR_FRAGMENT}
|
|
314
315
|
${CART_WARNING_FRAGMENT}
|
|
315
|
-
|
|
316
|
-
export const CART_REMOVE_LINES = `
|
|
316
|
+
`);
|
|
317
|
+
export const CART_REMOVE_LINES = composeOperation(`
|
|
317
318
|
mutation CartRemoveLines($id: ID!, $lineIds: [ID!]!) {
|
|
318
319
|
cartRemoveLines(id: $id, lineIds: $lineIds) {
|
|
319
320
|
cart { ...Cart }
|
|
@@ -324,8 +325,8 @@ export const CART_REMOVE_LINES = `
|
|
|
324
325
|
${CART_FRAGMENT}
|
|
325
326
|
${USER_ERROR_FRAGMENT}
|
|
326
327
|
${CART_WARNING_FRAGMENT}
|
|
327
|
-
|
|
328
|
-
export const CART_DISCOUNT_CODES_UPDATE = `
|
|
328
|
+
`);
|
|
329
|
+
export const CART_DISCOUNT_CODES_UPDATE = composeOperation(`
|
|
329
330
|
mutation CartDiscountCodesUpdate($id: ID!, $discountCodes: [String!]!) {
|
|
330
331
|
cartDiscountCodesUpdate(id: $id, discountCodes: $discountCodes) {
|
|
331
332
|
cart { ...Cart }
|
|
@@ -336,8 +337,8 @@ export const CART_DISCOUNT_CODES_UPDATE = `
|
|
|
336
337
|
${CART_FRAGMENT}
|
|
337
338
|
${USER_ERROR_FRAGMENT}
|
|
338
339
|
${CART_WARNING_FRAGMENT}
|
|
339
|
-
|
|
340
|
-
export const CART_UPDATE_NOTE = `
|
|
340
|
+
`);
|
|
341
|
+
export const CART_UPDATE_NOTE = composeOperation(`
|
|
341
342
|
mutation CartUpdateNote($id: ID!, $note: String!) {
|
|
342
343
|
cartUpdateNote(id: $id, note: $note) {
|
|
343
344
|
cart { ...Cart }
|
|
@@ -348,8 +349,8 @@ export const CART_UPDATE_NOTE = `
|
|
|
348
349
|
${CART_FRAGMENT}
|
|
349
350
|
${USER_ERROR_FRAGMENT}
|
|
350
351
|
${CART_WARNING_FRAGMENT}
|
|
351
|
-
|
|
352
|
-
export const CART_UPDATE_BUYER_IDENTITY = `
|
|
352
|
+
`);
|
|
353
|
+
export const CART_UPDATE_BUYER_IDENTITY = composeOperation(`
|
|
353
354
|
mutation CartUpdateBuyerIdentity($id: ID!, $buyerIdentity: CartBuyerIdentityInput!) {
|
|
354
355
|
cartUpdateBuyerIdentity(id: $id, buyerIdentity: $buyerIdentity) {
|
|
355
356
|
cart { ...Cart }
|
|
@@ -360,11 +361,11 @@ export const CART_UPDATE_BUYER_IDENTITY = `
|
|
|
360
361
|
${CART_FRAGMENT}
|
|
361
362
|
${USER_ERROR_FRAGMENT}
|
|
362
363
|
${CART_WARNING_FRAGMENT}
|
|
363
|
-
|
|
364
|
+
`);
|
|
364
365
|
// ---------------------------------------------------------------------------
|
|
365
366
|
// Phase 3 — Cart completion lifecycle mutations
|
|
366
367
|
// ---------------------------------------------------------------------------
|
|
367
|
-
export const CART_SET_SHIPPING_ADDRESS = `
|
|
368
|
+
export const CART_SET_SHIPPING_ADDRESS = composeOperation(`
|
|
368
369
|
mutation CartSetShippingAddress($input: CartSetShippingAddressInput!) {
|
|
369
370
|
cartSetShippingAddress(input: $input) {
|
|
370
371
|
cart { ...Cart }
|
|
@@ -375,8 +376,8 @@ export const CART_SET_SHIPPING_ADDRESS = `
|
|
|
375
376
|
${CART_FRAGMENT}
|
|
376
377
|
${USER_ERROR_FRAGMENT}
|
|
377
378
|
${CART_WARNING_FRAGMENT}
|
|
378
|
-
|
|
379
|
-
export const CART_SET_BILLING_ADDRESS = `
|
|
379
|
+
`);
|
|
380
|
+
export const CART_SET_BILLING_ADDRESS = composeOperation(`
|
|
380
381
|
mutation CartSetBillingAddress($input: CartSetBillingAddressInput!) {
|
|
381
382
|
cartSetBillingAddress(input: $input) {
|
|
382
383
|
cart { ...Cart }
|
|
@@ -387,8 +388,8 @@ export const CART_SET_BILLING_ADDRESS = `
|
|
|
387
388
|
${CART_FRAGMENT}
|
|
388
389
|
${USER_ERROR_FRAGMENT}
|
|
389
390
|
${CART_WARNING_FRAGMENT}
|
|
390
|
-
|
|
391
|
-
export const CART_SELECT_SHIPPING_METHOD = `
|
|
391
|
+
`);
|
|
392
|
+
export const CART_SELECT_SHIPPING_METHOD = composeOperation(`
|
|
392
393
|
mutation CartSelectShippingMethod($input: CartSelectShippingMethodInput!) {
|
|
393
394
|
cartSelectShippingMethod(input: $input) {
|
|
394
395
|
cart { ...Cart }
|
|
@@ -399,8 +400,8 @@ export const CART_SELECT_SHIPPING_METHOD = `
|
|
|
399
400
|
${CART_FRAGMENT}
|
|
400
401
|
${USER_ERROR_FRAGMENT}
|
|
401
402
|
${CART_WARNING_FRAGMENT}
|
|
402
|
-
|
|
403
|
-
export const CART_SELECT_PAYMENT_METHOD = `
|
|
403
|
+
`);
|
|
404
|
+
export const CART_SELECT_PAYMENT_METHOD = composeOperation(`
|
|
404
405
|
mutation CartSelectPaymentMethod($input: CartSelectPaymentMethodInput!) {
|
|
405
406
|
cartSelectPaymentMethod(input: $input) {
|
|
406
407
|
cart { ...Cart }
|
|
@@ -411,8 +412,8 @@ export const CART_SELECT_PAYMENT_METHOD = `
|
|
|
411
412
|
${CART_FRAGMENT}
|
|
412
413
|
${USER_ERROR_FRAGMENT}
|
|
413
414
|
${CART_WARNING_FRAGMENT}
|
|
414
|
-
|
|
415
|
-
export const CART_APPLY_GIFT_CARD = `
|
|
415
|
+
`);
|
|
416
|
+
export const CART_APPLY_GIFT_CARD = composeOperation(`
|
|
416
417
|
mutation CartApplyGiftCard($input: CartApplyGiftCardInput!) {
|
|
417
418
|
cartApplyGiftCard(input: $input) {
|
|
418
419
|
cart { ...Cart }
|
|
@@ -423,8 +424,8 @@ export const CART_APPLY_GIFT_CARD = `
|
|
|
423
424
|
${CART_FRAGMENT}
|
|
424
425
|
${USER_ERROR_FRAGMENT}
|
|
425
426
|
${CART_WARNING_FRAGMENT}
|
|
426
|
-
|
|
427
|
-
export const CART_REMOVE_GIFT_CARD = `
|
|
427
|
+
`);
|
|
428
|
+
export const CART_REMOVE_GIFT_CARD = composeOperation(`
|
|
428
429
|
mutation CartRemoveGiftCard($input: CartRemoveGiftCardInput!) {
|
|
429
430
|
cartRemoveGiftCard(input: $input) {
|
|
430
431
|
cart { ...Cart }
|
|
@@ -435,8 +436,8 @@ export const CART_REMOVE_GIFT_CARD = `
|
|
|
435
436
|
${CART_FRAGMENT}
|
|
436
437
|
${USER_ERROR_FRAGMENT}
|
|
437
438
|
${CART_WARNING_FRAGMENT}
|
|
438
|
-
|
|
439
|
-
export const CART_UPDATE_GIFT_CARD_RECIPIENT = `
|
|
439
|
+
`);
|
|
440
|
+
export const CART_UPDATE_GIFT_CARD_RECIPIENT = composeOperation(`
|
|
440
441
|
mutation CartUpdateGiftCardRecipient($input: CartUpdateGiftCardRecipientInput!) {
|
|
441
442
|
cartUpdateGiftCardRecipient(input: $input) {
|
|
442
443
|
cart { ...Cart }
|
|
@@ -447,30 +448,28 @@ export const CART_UPDATE_GIFT_CARD_RECIPIENT = `
|
|
|
447
448
|
${CART_FRAGMENT}
|
|
448
449
|
${USER_ERROR_FRAGMENT}
|
|
449
450
|
${CART_WARNING_FRAGMENT}
|
|
450
|
-
|
|
451
|
+
`);
|
|
451
452
|
/**
|
|
452
|
-
* cartComplete — returns
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
453
|
+
* cartComplete — returns the Order created from the cart (carrying
|
|
454
|
+
* `canCreatePayment` + `paymentMethodType` signals for post-completion payment
|
|
455
|
+
* flow decisions). The cart itself is NOT returned — after completion it is
|
|
456
|
+
* CONVERTED/locked, so the storefront drops its local cart and works with the
|
|
457
|
+
* Order. `order` is non-null on success. `paymentUrl` is intentionally NOT in
|
|
458
|
+
* the payload (Decision D4) — the storefront calls a separate `paymentCreate`
|
|
459
|
+
* mutation after checking `order.canCreatePayment`.
|
|
459
460
|
*/
|
|
460
|
-
export const CART_COMPLETE = `
|
|
461
|
+
export const CART_COMPLETE = composeOperation(`
|
|
461
462
|
mutation CartComplete($input: CartCompleteInput!) {
|
|
462
463
|
cartComplete(input: $input) {
|
|
463
|
-
cart { ...Cart }
|
|
464
464
|
order { ...Order }
|
|
465
465
|
userErrors { ...UserError }
|
|
466
466
|
warnings { ...CartWarning }
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
|
-
${CART_FRAGMENT}
|
|
470
469
|
${ORDER_FRAGMENT}
|
|
471
470
|
${USER_ERROR_FRAGMENT}
|
|
472
471
|
${CART_WARNING_FRAGMENT}
|
|
473
|
-
|
|
472
|
+
`);
|
|
474
473
|
/**
|
|
475
474
|
* cartValidateDiscountCode Query — read-only preview discount applicability
|
|
476
475
|
* (Decision D3). No cart side effects; storefront UI używa do inline feedback
|
|
@@ -479,7 +478,7 @@ export const CART_COMPLETE = `
|
|
|
479
478
|
* Caching guidance: `fetchPolicy: 'network-only'` lub key zawierający
|
|
480
479
|
* `cart.subtotal` (discount eligibility może zależeć od minimum order amount).
|
|
481
480
|
*/
|
|
482
|
-
export const CART_VALIDATE_DISCOUNT_CODE = `
|
|
481
|
+
export const CART_VALIDATE_DISCOUNT_CODE = composeOperation(`
|
|
483
482
|
query CartValidateDiscountCode($cartId: ID!, $discountCode: String!) {
|
|
484
483
|
cartValidateDiscountCode(cartId: $cartId, discountCode: $discountCode) {
|
|
485
484
|
isValid
|
|
@@ -499,4 +498,4 @@ export const CART_VALIDATE_DISCOUNT_CODE = `
|
|
|
499
498
|
}
|
|
500
499
|
}
|
|
501
500
|
}
|
|
502
|
-
|
|
501
|
+
`);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* composeOperation — assemble a GraphQL operation string from an operation body
|
|
3
|
+
* plus its fragment definitions, deduplicating fragments by name.
|
|
4
|
+
*
|
|
5
|
+
* The SDK hand-maintains operation strings (no codegen) by concatenating fragment
|
|
6
|
+
* constants. Each constant carries its own transitive dependency closure — e.g.
|
|
7
|
+
* the Cart fragment tree pulls in `Money`, and the Order fragment tree pulls in
|
|
8
|
+
* `Money` too. When one operation selects two fields whose fragment trees overlap
|
|
9
|
+
* (the only case today: `cartComplete` returns both `cart` and `order`), the naive
|
|
10
|
+
* concatenation emits the shared fragment twice → GraphQL `UniqueFragmentNames`
|
|
11
|
+
* violation → the server rejects the whole request (HTTP 400).
|
|
12
|
+
*
|
|
13
|
+
* `composeOperation` scans the concatenated string, extracts every
|
|
14
|
+
* `fragment Name on Type { ... }` block (brace-matched), keeps the first
|
|
15
|
+
* occurrence of each name, and reassembles: operation body first, then each
|
|
16
|
+
* unique fragment. Every exported operation is wrapped in it, so a future
|
|
17
|
+
* operation combining two fragment trees can never reintroduce the collision.
|
|
18
|
+
*
|
|
19
|
+
* Pure string processing — no `graphql` dependency, so `core/` stays 0-deps.
|
|
20
|
+
* Inputs are our own controlled operation constants (no GraphQL string literals
|
|
21
|
+
* or comments), so the brace-matcher does not need a full lexer.
|
|
22
|
+
*/
|
|
23
|
+
export declare function composeOperation(raw: string): string;
|
|
24
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../../src/core/operations/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuCpD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* composeOperation — assemble a GraphQL operation string from an operation body
|
|
3
|
+
* plus its fragment definitions, deduplicating fragments by name.
|
|
4
|
+
*
|
|
5
|
+
* The SDK hand-maintains operation strings (no codegen) by concatenating fragment
|
|
6
|
+
* constants. Each constant carries its own transitive dependency closure — e.g.
|
|
7
|
+
* the Cart fragment tree pulls in `Money`, and the Order fragment tree pulls in
|
|
8
|
+
* `Money` too. When one operation selects two fields whose fragment trees overlap
|
|
9
|
+
* (the only case today: `cartComplete` returns both `cart` and `order`), the naive
|
|
10
|
+
* concatenation emits the shared fragment twice → GraphQL `UniqueFragmentNames`
|
|
11
|
+
* violation → the server rejects the whole request (HTTP 400).
|
|
12
|
+
*
|
|
13
|
+
* `composeOperation` scans the concatenated string, extracts every
|
|
14
|
+
* `fragment Name on Type { ... }` block (brace-matched), keeps the first
|
|
15
|
+
* occurrence of each name, and reassembles: operation body first, then each
|
|
16
|
+
* unique fragment. Every exported operation is wrapped in it, so a future
|
|
17
|
+
* operation combining two fragment trees can never reintroduce the collision.
|
|
18
|
+
*
|
|
19
|
+
* Pure string processing — no `graphql` dependency, so `core/` stays 0-deps.
|
|
20
|
+
* Inputs are our own controlled operation constants (no GraphQL string literals
|
|
21
|
+
* or comments), so the brace-matcher does not need a full lexer.
|
|
22
|
+
*/
|
|
23
|
+
export function composeOperation(raw) {
|
|
24
|
+
const fragmentStart = /fragment\s+(\w+)\s+on\s+\w+\s*\{/g;
|
|
25
|
+
const fragments = new Map();
|
|
26
|
+
const bodyParts = [];
|
|
27
|
+
let cursor = 0;
|
|
28
|
+
let match;
|
|
29
|
+
while ((match = fragmentStart.exec(raw)) !== null) {
|
|
30
|
+
const blockStart = match.index;
|
|
31
|
+
// Text before this fragment — the operation body on the first iteration,
|
|
32
|
+
// inter-fragment whitespace afterwards.
|
|
33
|
+
bodyParts.push(raw.slice(cursor, blockStart));
|
|
34
|
+
// Brace-match from the fragment's opening `{` to its closing `}`. Nested
|
|
35
|
+
// braces (field arguments like `url(transform: { maxWidth: 300 })`) net out.
|
|
36
|
+
let depth = 1;
|
|
37
|
+
let i = blockStart + match[0].length;
|
|
38
|
+
while (i < raw.length && depth > 0) {
|
|
39
|
+
const ch = raw[i];
|
|
40
|
+
if (ch === '{')
|
|
41
|
+
depth++;
|
|
42
|
+
else if (ch === '}')
|
|
43
|
+
depth--;
|
|
44
|
+
i++;
|
|
45
|
+
}
|
|
46
|
+
const name = match[1];
|
|
47
|
+
if (!fragments.has(name)) {
|
|
48
|
+
fragments.set(name, raw.slice(blockStart, i).trim());
|
|
49
|
+
}
|
|
50
|
+
cursor = i;
|
|
51
|
+
fragmentStart.lastIndex = i;
|
|
52
|
+
}
|
|
53
|
+
bodyParts.push(raw.slice(cursor));
|
|
54
|
+
const body = bodyParts.join('').trim();
|
|
55
|
+
return fragments.size > 0
|
|
56
|
+
? [body, ...fragments.values()].join('\n\n')
|
|
57
|
+
: body;
|
|
58
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doswiftly/storefront-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"description": "Storefront runtime SDK for DoSwiftly Commerce — layered transport, middleware pipeline, React providers, Zustand stores, cache strategies. 0 runtime dependencies in core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|