@doswiftly/storefront-sdk 9.1.0 → 10.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.
@@ -2,13 +2,14 @@
2
2
  * Cart GraphQL operations — manual query strings (no codegen).
3
3
  *
4
4
  * SSOT: packages/backend/src/commerce/storefront-graphql/operations/
5
- * - fragments.graphql (CartCost, CartLineCost, CartLine, Cart, etc.)
5
+ * - fragments.graphql (CartCost, CartLineCost, CartLine, Cart, Order, CartWarning, etc.)
6
6
  * - queries.graphql (Cart query)
7
- * - mutations.graphql (cartCreate, cartLinesAdd, etc.)
7
+ * - mutations.graphql (cartCreate, cartAddLines, etc.)
8
8
  *
9
9
  * Validate drift: pnpm test:contract (cart-operations-drift test)
10
10
  *
11
- * Cart mutations always return full Cart + userErrors.
11
+ * Cart mutations always return full Cart + userErrors + warnings (non-fatal hints).
12
+ * Drift detection: PreToolUse hook validuje strings przeciwko storefront-operations/schema.graphql.
12
13
  */
13
14
  // ---------------------------------------------------------------------------
14
15
  // Shared fragments (matching SSOT fragments.graphql)
@@ -135,6 +136,53 @@ const CART_DISCOUNT_ALLOCATION_FRAGMENT = `
135
136
  amount { ...Money }
136
137
  }
137
138
  `;
139
+ const MAILING_ADDRESS_FRAGMENT = `
140
+ fragment MailingAddress on MailingAddress {
141
+ id
142
+ firstName
143
+ lastName
144
+ name
145
+ company
146
+ streetLine1
147
+ streetLine2
148
+ city
149
+ state
150
+ stateCode
151
+ country
152
+ countryCode
153
+ postalCode
154
+ phone
155
+ isDefault
156
+ }
157
+ `;
158
+ const CART_SHIPPING_METHOD_FRAGMENT = `
159
+ fragment CartShippingMethod on CartShippingMethod {
160
+ handle
161
+ title
162
+ price { ...Money }
163
+ }
164
+ `;
165
+ const CART_APPLIED_GIFT_CARD_FRAGMENT = `
166
+ fragment CartAppliedGiftCard on CartAppliedGiftCard {
167
+ maskedCode
168
+ lastCharacters
169
+ appliedAmount { ...Money }
170
+ remainingBalance { ...Money }
171
+ }
172
+ `;
173
+ const CART_SELECTED_PAYMENT_METHOD_FRAGMENT = `
174
+ fragment CartSelectedPaymentMethod on PaymentMethod {
175
+ id
176
+ name
177
+ provider
178
+ type
179
+ icon
180
+ description
181
+ isDefault
182
+ supportedCurrencies
183
+ position
184
+ }
185
+ `;
138
186
  const CART_FRAGMENT = `
139
187
  fragment Cart on Cart {
140
188
  id
@@ -155,6 +203,13 @@ const CART_FRAGMENT = `
155
203
  discountAllocations { ...CartDiscountAllocation }
156
204
  note
157
205
  attributes { key value }
206
+ email
207
+ phone
208
+ shippingAddress { ...MailingAddress }
209
+ billingAddress { ...MailingAddress }
210
+ selectedShippingMethod { ...CartShippingMethod }
211
+ selectedPaymentMethod { ...CartSelectedPaymentMethod }
212
+ appliedGiftCards { ...CartAppliedGiftCard }
158
213
  createdAt
159
214
  updatedAt
160
215
  }
@@ -163,8 +218,37 @@ const CART_FRAGMENT = `
163
218
  ${CART_BUYER_IDENTITY_FRAGMENT}
164
219
  ${CART_DISCOUNT_CODE_FRAGMENT}
165
220
  ${CART_DISCOUNT_ALLOCATION_FRAGMENT}
221
+ ${MAILING_ADDRESS_FRAGMENT}
222
+ ${CART_SHIPPING_METHOD_FRAGMENT}
223
+ ${CART_APPLIED_GIFT_CARD_FRAGMENT}
224
+ ${CART_SELECTED_PAYMENT_METHOD_FRAGMENT}
166
225
  ${PAGE_INFO_FRAGMENT}
167
226
  `;
227
+ const ORDER_FRAGMENT = `
228
+ fragment Order on Order {
229
+ id
230
+ orderNumber
231
+ totals {
232
+ total { ...Money }
233
+ subtotal { ...Money }
234
+ totalTax { ...Money }
235
+ totalShipping { ...Money }
236
+ }
237
+ status
238
+ paymentStatus
239
+ fulfillmentStatus
240
+ processedAt
241
+ confirmedAt
242
+ cancelledAt
243
+ expiredAt
244
+ shippingAddress { ...MailingAddress }
245
+ itemCount
246
+ canCreatePayment
247
+ paymentMethodType
248
+ }
249
+ ${MONEY_FRAGMENT}
250
+ ${MAILING_ADDRESS_FRAGMENT}
251
+ `;
168
252
  const USER_ERROR_FRAGMENT = `
169
253
  fragment UserError on UserError {
170
254
  message
@@ -172,6 +256,13 @@ const USER_ERROR_FRAGMENT = `
172
256
  field
173
257
  }
174
258
  `;
259
+ const CART_WARNING_FRAGMENT = `
260
+ fragment CartWarning on CartWarning {
261
+ message
262
+ code
263
+ target
264
+ }
265
+ `;
175
266
  // ---------------------------------------------------------------------------
176
267
  // Queries
177
268
  // ---------------------------------------------------------------------------
@@ -191,68 +282,221 @@ export const CART_CREATE = `
191
282
  cartCreate(input: $input) {
192
283
  cart { ...Cart }
193
284
  userErrors { ...UserError }
285
+ warnings { ...CartWarning }
194
286
  }
195
287
  }
196
288
  ${CART_FRAGMENT}
197
289
  ${USER_ERROR_FRAGMENT}
290
+ ${CART_WARNING_FRAGMENT}
198
291
  `;
199
- export const CART_LINES_ADD = `
200
- mutation CartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {
201
- cartLinesAdd(cartId: $cartId, lines: $lines) {
292
+ export const CART_ADD_LINES = `
293
+ mutation CartAddLines($id: ID!, $lines: [CartLineInput!]!) {
294
+ cartAddLines(id: $id, lines: $lines) {
202
295
  cart { ...Cart }
203
296
  userErrors { ...UserError }
297
+ warnings { ...CartWarning }
204
298
  }
205
299
  }
206
300
  ${CART_FRAGMENT}
207
301
  ${USER_ERROR_FRAGMENT}
302
+ ${CART_WARNING_FRAGMENT}
208
303
  `;
209
- export const CART_LINES_UPDATE = `
210
- mutation CartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
211
- cartLinesUpdate(cartId: $cartId, lines: $lines) {
304
+ export const CART_UPDATE_LINES = `
305
+ mutation CartUpdateLines($id: ID!, $lines: [CartLineUpdateInput!]!) {
306
+ cartUpdateLines(id: $id, lines: $lines) {
212
307
  cart { ...Cart }
213
308
  userErrors { ...UserError }
309
+ warnings { ...CartWarning }
214
310
  }
215
311
  }
216
312
  ${CART_FRAGMENT}
217
313
  ${USER_ERROR_FRAGMENT}
314
+ ${CART_WARNING_FRAGMENT}
218
315
  `;
219
- export const CART_LINES_REMOVE = `
220
- mutation CartLinesRemove($cartId: ID!, $lineIds: [ID!]!) {
221
- cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {
316
+ export const CART_REMOVE_LINES = `
317
+ mutation CartRemoveLines($id: ID!, $lineIds: [ID!]!) {
318
+ cartRemoveLines(id: $id, lineIds: $lineIds) {
222
319
  cart { ...Cart }
223
320
  userErrors { ...UserError }
321
+ warnings { ...CartWarning }
224
322
  }
225
323
  }
226
324
  ${CART_FRAGMENT}
227
325
  ${USER_ERROR_FRAGMENT}
326
+ ${CART_WARNING_FRAGMENT}
228
327
  `;
229
328
  export const CART_DISCOUNT_CODES_UPDATE = `
230
- mutation CartDiscountCodesUpdate($cartId: ID!, $discountCodes: [String!]!) {
231
- cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {
329
+ mutation CartDiscountCodesUpdate($id: ID!, $discountCodes: [String!]!) {
330
+ cartDiscountCodesUpdate(id: $id, discountCodes: $discountCodes) {
331
+ cart { ...Cart }
332
+ userErrors { ...UserError }
333
+ warnings { ...CartWarning }
334
+ }
335
+ }
336
+ ${CART_FRAGMENT}
337
+ ${USER_ERROR_FRAGMENT}
338
+ ${CART_WARNING_FRAGMENT}
339
+ `;
340
+ export const CART_UPDATE_NOTE = `
341
+ mutation CartUpdateNote($id: ID!, $note: String!) {
342
+ cartUpdateNote(id: $id, note: $note) {
343
+ cart { ...Cart }
344
+ userErrors { ...UserError }
345
+ warnings { ...CartWarning }
346
+ }
347
+ }
348
+ ${CART_FRAGMENT}
349
+ ${USER_ERROR_FRAGMENT}
350
+ ${CART_WARNING_FRAGMENT}
351
+ `;
352
+ export const CART_UPDATE_BUYER_IDENTITY = `
353
+ mutation CartUpdateBuyerIdentity($id: ID!, $buyerIdentity: CartBuyerIdentityInput!) {
354
+ cartUpdateBuyerIdentity(id: $id, buyerIdentity: $buyerIdentity) {
232
355
  cart { ...Cart }
233
356
  userErrors { ...UserError }
357
+ warnings { ...CartWarning }
234
358
  }
235
359
  }
236
360
  ${CART_FRAGMENT}
237
361
  ${USER_ERROR_FRAGMENT}
362
+ ${CART_WARNING_FRAGMENT}
238
363
  `;
239
- export const CART_NOTE_UPDATE = `
240
- mutation CartNoteUpdate($cartId: ID!, $note: String!) {
241
- cartNoteUpdate(cartId: $cartId, note: $note) {
364
+ // ---------------------------------------------------------------------------
365
+ // Phase 3 Cart completion lifecycle mutations
366
+ // ---------------------------------------------------------------------------
367
+ export const CART_SET_SHIPPING_ADDRESS = `
368
+ mutation CartSetShippingAddress($input: CartSetShippingAddressInput!) {
369
+ cartSetShippingAddress(input: $input) {
242
370
  cart { ...Cart }
243
371
  userErrors { ...UserError }
372
+ warnings { ...CartWarning }
244
373
  }
245
374
  }
246
375
  ${CART_FRAGMENT}
247
376
  ${USER_ERROR_FRAGMENT}
377
+ ${CART_WARNING_FRAGMENT}
248
378
  `;
249
- export const CART_BUYER_IDENTITY_UPDATE = `
250
- mutation CartBuyerIdentityUpdate($cartId: ID!, $buyerIdentity: CartBuyerIdentityInput!) {
251
- cartBuyerIdentityUpdate(cartId: $cartId, buyerIdentity: $buyerIdentity) {
379
+ export const CART_SET_BILLING_ADDRESS = `
380
+ mutation CartSetBillingAddress($input: CartSetBillingAddressInput!) {
381
+ cartSetBillingAddress(input: $input) {
252
382
  cart { ...Cart }
253
383
  userErrors { ...UserError }
384
+ warnings { ...CartWarning }
254
385
  }
255
386
  }
256
387
  ${CART_FRAGMENT}
257
388
  ${USER_ERROR_FRAGMENT}
389
+ ${CART_WARNING_FRAGMENT}
390
+ `;
391
+ export const CART_SELECT_SHIPPING_METHOD = `
392
+ mutation CartSelectShippingMethod($input: CartSelectShippingMethodInput!) {
393
+ cartSelectShippingMethod(input: $input) {
394
+ cart { ...Cart }
395
+ userErrors { ...UserError }
396
+ warnings { ...CartWarning }
397
+ }
398
+ }
399
+ ${CART_FRAGMENT}
400
+ ${USER_ERROR_FRAGMENT}
401
+ ${CART_WARNING_FRAGMENT}
402
+ `;
403
+ export const CART_SELECT_PAYMENT_METHOD = `
404
+ mutation CartSelectPaymentMethod($input: CartSelectPaymentMethodInput!) {
405
+ cartSelectPaymentMethod(input: $input) {
406
+ cart { ...Cart }
407
+ userErrors { ...UserError }
408
+ warnings { ...CartWarning }
409
+ }
410
+ }
411
+ ${CART_FRAGMENT}
412
+ ${USER_ERROR_FRAGMENT}
413
+ ${CART_WARNING_FRAGMENT}
414
+ `;
415
+ export const CART_APPLY_GIFT_CARD = `
416
+ mutation CartApplyGiftCard($input: CartApplyGiftCardInput!) {
417
+ cartApplyGiftCard(input: $input) {
418
+ cart { ...Cart }
419
+ userErrors { ...UserError }
420
+ warnings { ...CartWarning }
421
+ }
422
+ }
423
+ ${CART_FRAGMENT}
424
+ ${USER_ERROR_FRAGMENT}
425
+ ${CART_WARNING_FRAGMENT}
426
+ `;
427
+ export const CART_REMOVE_GIFT_CARD = `
428
+ mutation CartRemoveGiftCard($input: CartRemoveGiftCardInput!) {
429
+ cartRemoveGiftCard(input: $input) {
430
+ cart { ...Cart }
431
+ userErrors { ...UserError }
432
+ warnings { ...CartWarning }
433
+ }
434
+ }
435
+ ${CART_FRAGMENT}
436
+ ${USER_ERROR_FRAGMENT}
437
+ ${CART_WARNING_FRAGMENT}
438
+ `;
439
+ export const CART_UPDATE_GIFT_CARD_RECIPIENT = `
440
+ mutation CartUpdateGiftCardRecipient($input: CartUpdateGiftCardRecipientInput!) {
441
+ cartUpdateGiftCardRecipient(input: $input) {
442
+ cart { ...Cart }
443
+ userErrors { ...UserError }
444
+ warnings { ...CartWarning }
445
+ }
446
+ }
447
+ ${CART_FRAGMENT}
448
+ ${USER_ERROR_FRAGMENT}
449
+ ${CART_WARNING_FRAGMENT}
450
+ `;
451
+ /**
452
+ * cartComplete — returns Cart + Order (z canCreatePayment + paymentMethodType
453
+ * signal dla post-payment flow decisions). paymentUrl NIE w payload (Decision D4) —
454
+ * storefront wywołuje osobne `paymentCreate` mutation (po sprawdzeniu order.canCreatePayment).
455
+ *
456
+ * Note (backend resolver Phase 4 follow-up): obecnie cartComplete może zwrócić
457
+ * `order: null` — storefront powinien fallback do `order(id, orderNumber)` query
458
+ * jeśli null. SDK type sygnalizuje to przez `order: Order | null`.
459
+ */
460
+ export const CART_COMPLETE = `
461
+ mutation CartComplete($input: CartCompleteInput!) {
462
+ cartComplete(input: $input) {
463
+ cart { ...Cart }
464
+ order { ...Order }
465
+ userErrors { ...UserError }
466
+ warnings { ...CartWarning }
467
+ }
468
+ }
469
+ ${CART_FRAGMENT}
470
+ ${ORDER_FRAGMENT}
471
+ ${USER_ERROR_FRAGMENT}
472
+ ${CART_WARNING_FRAGMENT}
473
+ `;
474
+ /**
475
+ * cartValidateDiscountCode Query — read-only preview discount applicability
476
+ * (Decision D3). No cart side effects; storefront UI używa do inline feedback
477
+ * gdy klient wpisuje kod (przed wywołaniem cartDiscountCodesUpdate).
478
+ *
479
+ * Caching guidance: `fetchPolicy: 'network-only'` lub key zawierający
480
+ * `cart.subtotal` (discount eligibility może zależeć od minimum order amount).
481
+ */
482
+ export const CART_VALIDATE_DISCOUNT_CODE = `
483
+ query CartValidateDiscountCode($cartId: ID!, $discountCode: String!) {
484
+ cartValidateDiscountCode(cartId: $cartId, discountCode: $discountCode) {
485
+ isValid
486
+ discount {
487
+ code
488
+ title
489
+ type
490
+ value
491
+ discountAmount {
492
+ amount
493
+ currencyCode
494
+ }
495
+ }
496
+ error {
497
+ code
498
+ message
499
+ }
500
+ }
501
+ }
258
502
  `;
@@ -13,15 +13,16 @@
13
13
  * ```
14
14
  */
15
15
  import type { Cart, CartLineInput, CartLineUpdateInput } from '../../core/cart/types';
16
+ import type { CartMutationOutcome } from '../../core/cart/cart-client';
16
17
  export declare function useCartManager(): {
17
18
  getCart: () => Promise<Cart | null>;
18
19
  addItem: (lines: CartLineInput[], options?: {
19
20
  forceNewCart?: boolean;
20
- }) => Promise<Cart>;
21
- updateItem: (lines: CartLineUpdateInput[]) => Promise<Cart>;
22
- removeItem: (lineIds: string[]) => Promise<Cart>;
23
- updateDiscountCodes: (codes: string[]) => Promise<Cart>;
24
- updateNote: (note: string) => Promise<Cart>;
21
+ }) => Promise<CartMutationOutcome>;
22
+ updateItem: (lines: CartLineUpdateInput[]) => Promise<CartMutationOutcome>;
23
+ removeItem: (lineIds: string[]) => Promise<CartMutationOutcome>;
24
+ updateDiscountCodes: (codes: string[]) => Promise<CartMutationOutcome>;
25
+ updateNote: (note: string) => Promise<CartMutationOutcome>;
25
26
  clearCart: () => void;
26
27
  getCartId: () => string | null;
27
28
  isLoading: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"use-cart-manager.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-cart-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,mBAAmB,EAA2C,MAAM,uBAAuB,CAAC;AAwB/H,wBAAgB,cAAc;mBAiCU,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;qBAoBjD,aAAa,EAAE,YACZ;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KACnC,OAAO,CAAC,IAAI,CAAC;wBA0BP,mBAAmB,EAAE,KAC3B,OAAO,CAAC,IAAI,CAAC;0BAuB+B,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CAAC;iCAuBjB,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CAAC;uBAoBlC,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;;qBA2BhC,MAAM,GAAG,IAAI;;;EAiBhD"}
1
+ {"version":3,"file":"use-cart-manager.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-cart-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAwBvE,wBAAgB,cAAc;mBAiCU,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;qBAoBjD,aAAa,EAAE,YACZ;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KACnC,OAAO,CAAC,mBAAmB,CAAC;wBAyBtB,mBAAmB,EAAE,KAC3B,OAAO,CAAC,mBAAmB,CAAC;0BAuBgB,MAAM,EAAE,KAAG,OAAO,CAAC,mBAAmB,CAAC;iCAuBhC,MAAM,EAAE,KAAG,OAAO,CAAC,mBAAmB,CAAC;uBAoBjD,MAAM,KAAG,OAAO,CAAC,mBAAmB,CAAC;;qBA2B/C,MAAM,GAAG,IAAI;;;EAiBhD"}
@@ -49,7 +49,7 @@ export function useCartManager() {
49
49
  if (existing)
50
50
  return existing;
51
51
  }
52
- const cart = await cartClient.create();
52
+ const { cart } = await cartClient.create();
53
53
  setCartIdCookie(cart.id);
54
54
  return cart.id;
55
55
  }, [cartClient]);
@@ -90,8 +90,7 @@ export function useCartManager() {
90
90
  setIsLoading(true);
91
91
  try {
92
92
  const cartId = await getOrCreateCartId(options?.forceNewCart);
93
- const cart = await cartClient.addItems(cartId, lines);
94
- return cart;
93
+ return await cartClient.addItems(cartId, lines);
95
94
  }
96
95
  catch (err) {
97
96
  if (isCartExpired(err) && !options?.forceNewCart) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doswiftly/storefront-sdk",
3
- "version": "9.1.0",
3
+ "version": "10.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": [