@doswiftly/storefront-sdk 4.0.0 → 4.2.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.
Files changed (113) hide show
  1. package/README.md +51 -9
  2. package/dist/core/bot-protection/abstract-manager.d.ts +57 -0
  3. package/dist/core/bot-protection/abstract-manager.d.ts.map +1 -0
  4. package/dist/core/bot-protection/abstract-manager.js +144 -0
  5. package/dist/core/bot-protection/create-manager.d.ts +15 -0
  6. package/dist/core/bot-protection/create-manager.d.ts.map +1 -0
  7. package/dist/core/bot-protection/create-manager.js +33 -0
  8. package/dist/core/bot-protection/eucaptcha-manager.d.ts +15 -0
  9. package/dist/core/bot-protection/eucaptcha-manager.d.ts.map +1 -0
  10. package/dist/core/bot-protection/eucaptcha-manager.js +76 -0
  11. package/dist/core/bot-protection/fallback-manager.d.ts +18 -0
  12. package/dist/core/bot-protection/fallback-manager.d.ts.map +1 -0
  13. package/dist/core/bot-protection/fallback-manager.js +42 -0
  14. package/dist/core/bot-protection/turnstile-manager.d.ts +15 -0
  15. package/dist/core/bot-protection/turnstile-manager.d.ts.map +1 -0
  16. package/dist/core/bot-protection/turnstile-manager.js +78 -0
  17. package/dist/core/cart/cookie-config.d.ts +14 -0
  18. package/dist/core/cart/cookie-config.d.ts.map +1 -0
  19. package/dist/core/cart/cookie-config.js +13 -0
  20. package/dist/core/currency/cookie-config.d.ts +14 -0
  21. package/dist/core/currency/cookie-config.d.ts.map +1 -0
  22. package/dist/core/currency/cookie-config.js +13 -0
  23. package/dist/core/image.d.ts +55 -0
  24. package/dist/core/image.d.ts.map +1 -0
  25. package/dist/core/image.js +48 -0
  26. package/dist/core/index.d.ts +8 -0
  27. package/dist/core/index.d.ts.map +1 -1
  28. package/dist/core/index.js +13 -0
  29. package/dist/core/language/cookie-config.d.ts +14 -0
  30. package/dist/core/language/cookie-config.d.ts.map +1 -0
  31. package/dist/core/language/cookie-config.js +13 -0
  32. package/dist/core/middleware/bot-protection.d.ts +71 -0
  33. package/dist/core/middleware/bot-protection.d.ts.map +1 -0
  34. package/dist/core/middleware/bot-protection.js +63 -0
  35. package/dist/core/middleware/currency.d.ts.map +1 -1
  36. package/dist/core/middleware/currency.js +2 -1
  37. package/dist/core/middleware/language.d.ts +18 -0
  38. package/dist/core/middleware/language.d.ts.map +1 -0
  39. package/dist/core/middleware/language.js +25 -0
  40. package/dist/react/bot-protection/bot-protection-context.d.ts +12 -0
  41. package/dist/react/bot-protection/bot-protection-context.d.ts.map +1 -0
  42. package/dist/react/bot-protection/bot-protection-context.js +9 -0
  43. package/dist/react/bot-protection/bot-protection-widget.d.ts +13 -0
  44. package/dist/react/bot-protection/bot-protection-widget.d.ts.map +1 -0
  45. package/dist/react/bot-protection/bot-protection-widget.js +34 -0
  46. package/dist/react/cookies.d.ts +17 -0
  47. package/dist/react/cookies.d.ts.map +1 -1
  48. package/dist/react/cookies.js +36 -3
  49. package/dist/react/hooks/use-bot-protection.d.ts +16 -0
  50. package/dist/react/hooks/use-bot-protection.d.ts.map +1 -0
  51. package/dist/react/hooks/use-bot-protection.js +24 -0
  52. package/dist/react/index.d.ts +10 -1
  53. package/dist/react/index.d.ts.map +1 -1
  54. package/dist/react/index.js +9 -1
  55. package/dist/react/providers/language-provider.d.ts +18 -0
  56. package/dist/react/providers/language-provider.d.ts.map +1 -0
  57. package/dist/react/providers/language-provider.js +24 -0
  58. package/dist/react/providers/storefront-client-provider.d.ts +7 -2
  59. package/dist/react/providers/storefront-client-provider.d.ts.map +1 -1
  60. package/dist/react/providers/storefront-client-provider.js +14 -3
  61. package/dist/react/providers/storefront-provider.d.ts +7 -1
  62. package/dist/react/providers/storefront-provider.d.ts.map +1 -1
  63. package/dist/react/providers/storefront-provider.js +11 -4
  64. package/dist/react/stores/cart.context.d.ts +12 -0
  65. package/dist/react/stores/cart.context.d.ts.map +1 -0
  66. package/dist/react/stores/cart.context.js +3 -0
  67. package/dist/react/stores/cart.store.d.ts +71 -0
  68. package/dist/react/stores/cart.store.d.ts.map +1 -0
  69. package/dist/react/stores/cart.store.js +166 -0
  70. package/dist/react/stores/currency.store.d.ts +6 -9
  71. package/dist/react/stores/currency.store.d.ts.map +1 -1
  72. package/dist/react/stores/currency.store.js +5 -22
  73. package/dist/react/stores/language.store.d.ts +33 -0
  74. package/dist/react/stores/language.store.d.ts.map +1 -0
  75. package/dist/react/stores/language.store.js +67 -0
  76. package/dist/react/stores/store-context.d.ts +5 -0
  77. package/dist/react/stores/store-context.d.ts.map +1 -1
  78. package/dist/react/stores/store-context.js +14 -0
  79. package/dist/react/types/shop-config.d.ts +19 -0
  80. package/dist/react/types/shop-config.d.ts.map +1 -0
  81. package/dist/react/types/shop-config.js +7 -0
  82. package/package.json +1 -1
  83. package/src/__tests__/unit/bot-protection.test.ts +461 -0
  84. package/src/__tests__/unit/cart-store.test.ts +349 -0
  85. package/src/core/bot-protection/abstract-manager.ts +185 -0
  86. package/src/core/bot-protection/create-manager.ts +37 -0
  87. package/src/core/bot-protection/eucaptcha-manager.ts +88 -0
  88. package/src/core/bot-protection/fallback-manager.ts +43 -0
  89. package/src/core/bot-protection/turnstile-manager.ts +92 -0
  90. package/src/core/bot-protection/types/eucaptcha.d.ts +28 -0
  91. package/src/core/bot-protection/types/turnstile.d.ts +33 -0
  92. package/src/core/cart/cookie-config.ts +13 -0
  93. package/src/core/currency/cookie-config.ts +13 -0
  94. package/src/core/image.ts +75 -0
  95. package/src/core/index.ts +30 -0
  96. package/src/core/language/cookie-config.ts +13 -0
  97. package/src/core/middleware/bot-protection.ts +140 -0
  98. package/src/core/middleware/currency.ts +2 -1
  99. package/src/core/middleware/language.ts +30 -0
  100. package/src/react/bot-protection/bot-protection-context.ts +17 -0
  101. package/src/react/bot-protection/bot-protection-widget.tsx +46 -0
  102. package/src/react/cookies.ts +39 -4
  103. package/src/react/hooks/use-bot-protection.ts +31 -0
  104. package/src/react/index.ts +27 -1
  105. package/src/react/providers/language-provider.tsx +34 -0
  106. package/src/react/providers/storefront-client-provider.tsx +20 -3
  107. package/src/react/providers/storefront-provider.tsx +34 -6
  108. package/src/react/stores/cart.context.ts +10 -0
  109. package/src/react/stores/cart.store.ts +254 -0
  110. package/src/react/stores/currency.store.ts +12 -32
  111. package/src/react/stores/language.store.ts +90 -0
  112. package/src/react/stores/store-context.tsx +21 -0
  113. package/src/react/types/shop-config.ts +22 -0
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Currency configuration constants — platform contract.
3
+ *
4
+ * Used by:
5
+ * - SDK currency store (client-side cookie read/write)
6
+ * - SDK currency middleware (X-Preferred-Currency header)
7
+ * - Server-side currency detection (SSR helpers)
8
+ *
9
+ * Single cookie for preferred currency persistence.
10
+ */
11
+ export declare const CURRENCY_COOKIE_NAME = "preferred-currency";
12
+ export declare const CURRENCY_COOKIE_MAX_AGE: number;
13
+ export declare const CURRENCY_HEADER_NAME = "X-Preferred-Currency";
14
+ //# sourceMappingURL=cookie-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-config.d.ts","sourceRoot":"","sources":["../../../src/core/currency/cookie-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AACzD,eAAO,MAAM,uBAAuB,QAAqB,CAAC;AAC1D,eAAO,MAAM,oBAAoB,yBAAyB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Currency configuration constants — platform contract.
3
+ *
4
+ * Used by:
5
+ * - SDK currency store (client-side cookie read/write)
6
+ * - SDK currency middleware (X-Preferred-Currency header)
7
+ * - Server-side currency detection (SSR helpers)
8
+ *
9
+ * Single cookie for preferred currency persistence.
10
+ */
11
+ export const CURRENCY_COOKIE_NAME = 'preferred-currency';
12
+ export const CURRENCY_COOKIE_MAX_AGE = 365 * 24 * 60 * 60; // 1 year
13
+ export const CURRENCY_HEADER_NAME = 'X-Preferred-Currency';
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Image utilities for DoSwiftly storefronts.
3
+ *
4
+ * Zero configuration — GraphQL API returns ready-to-use CDN URLs.
5
+ * The loader just appends resize query params. No keys, no env vars.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { storefrontImageLoader, type ImageData } from '@doswiftly/storefront-sdk';
10
+ *
11
+ * <Image loader={storefrontImageLoader} src={product.featuredImage.url} width={800} alt="..." />
12
+ * ```
13
+ */
14
+ /**
15
+ * Image data from GraphQL API (matches Image type in storefront schema).
16
+ */
17
+ export interface ImageData {
18
+ /** Image URL from GraphQL (ready-to-use CDN URL) */
19
+ url: string;
20
+ /** Alt text for accessibility + SEO */
21
+ altText?: string | null;
22
+ /** Original image width in pixels */
23
+ width?: number | null;
24
+ /** Original image height in pixels */
25
+ height?: number | null;
26
+ /** Image ID */
27
+ id?: string | null;
28
+ }
29
+ /**
30
+ * Next.js Image loader function signature.
31
+ */
32
+ export interface ImageLoaderParams {
33
+ src: string;
34
+ width: number;
35
+ quality?: number;
36
+ }
37
+ /**
38
+ * Next.js image loader for DoSwiftly storefronts.
39
+ *
40
+ * Zero configuration — works out of the box with GraphQL image URLs.
41
+ * Appends resize query params (?width=&quality=&format=) to the URL
42
+ * that backend already returned via GraphQL.
43
+ *
44
+ * Width is quantized to preset breakpoints for optimal CDN cache.
45
+ * No HMAC, no env vars, no setup — like Shopify Hydrogen's image loader.
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * import { storefrontImageLoader } from '@doswiftly/storefront-sdk';
50
+ *
51
+ * <Image loader={storefrontImageLoader} src={image.url} width={800} alt="..." />
52
+ * ```
53
+ */
54
+ export declare function storefrontImageLoader({ src, width, quality }: ImageLoaderParams): string;
55
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/core/image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe;IACf,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAeD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,MAAM,CAKxF"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Image utilities for DoSwiftly storefronts.
3
+ *
4
+ * Zero configuration — GraphQL API returns ready-to-use CDN URLs.
5
+ * The loader just appends resize query params. No keys, no env vars.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { storefrontImageLoader, type ImageData } from '@doswiftly/storefront-sdk';
10
+ *
11
+ * <Image loader={storefrontImageLoader} src={product.featuredImage.url} width={800} alt="..." />
12
+ * ```
13
+ */
14
+ /**
15
+ * Preset widths for CDN cache optimization.
16
+ * Loader quantizes requested width to the nearest preset — limits cache variants.
17
+ */
18
+ const PRESET_WIDTHS = [150, 320, 640, 750, 828, 1080, 1200, 1600, 1920, 2048];
19
+ function nearestPresetWidth(requested) {
20
+ for (const w of PRESET_WIDTHS) {
21
+ if (w >= requested)
22
+ return w;
23
+ }
24
+ return PRESET_WIDTHS[PRESET_WIDTHS.length - 1];
25
+ }
26
+ /**
27
+ * Next.js image loader for DoSwiftly storefronts.
28
+ *
29
+ * Zero configuration — works out of the box with GraphQL image URLs.
30
+ * Appends resize query params (?width=&quality=&format=) to the URL
31
+ * that backend already returned via GraphQL.
32
+ *
33
+ * Width is quantized to preset breakpoints for optimal CDN cache.
34
+ * No HMAC, no env vars, no setup — like Shopify Hydrogen's image loader.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * import { storefrontImageLoader } from '@doswiftly/storefront-sdk';
39
+ *
40
+ * <Image loader={storefrontImageLoader} src={image.url} width={800} alt="..." />
41
+ * ```
42
+ */
43
+ export function storefrontImageLoader({ src, width, quality }) {
44
+ const w = nearestPresetWidth(width);
45
+ const q = quality || 85;
46
+ const separator = src.includes('?') ? '&' : '?';
47
+ return `${src}${separator}width=${w}&quality=${q}&format=webp`;
48
+ }
@@ -37,9 +37,13 @@ export { createStorefrontClient } from './client/create-client';
37
37
  export type { StorefrontClient, StorefrontClientConfig, Middleware, ExecuteFn, GraphQLRequest, GraphQLResponse, GraphQLErrorInfo, UserError, CacheStrategy, CacheOptions, TypedDocumentString, } from './client/types';
38
38
  export { authMiddleware } from './middleware/auth';
39
39
  export { currencyMiddleware } from './middleware/currency';
40
+ export { languageMiddleware } from './middleware/language';
41
+ export { botProtectionMiddleware, BOT_PROTECTION_HEADER, type BotProtectionTokenProvider, type BotProtectionConfig, type BotProtectionProviderConfig, type BotProtectionMiddlewareOptions, type FailStrategy, } from './middleware/bot-protection';
40
42
  export { retryMiddleware, type RetryOptions } from './middleware/retry';
41
43
  export { timeoutMiddleware, type TimeoutOptions } from './middleware/timeout';
42
44
  export { errorMiddleware } from './middleware/errors';
45
+ export { createBotProtectionManager } from './bot-protection/create-manager';
46
+ export { FallbackBotProtectionManager } from './bot-protection/fallback-manager';
43
47
  export { StorefrontError, ErrorCodes, type StorefrontErrorOptions } from './errors';
44
48
  export { cacheNone, cacheShort, cacheLong, cachePrivate, cacheCustom, generateCacheControlHeader, type CacheOverrides, } from './cache';
45
49
  export { CartClient } from './cart/cart-client';
@@ -51,9 +55,13 @@ export { sanitizeHtml } from './helpers/sanitize-html';
51
55
  export { normalizeConnection, type Connection, type ConnectionEdge, type ConnectionPageInfo, type NormalizedConnection, } from './helpers/normalize-connection';
52
56
  export { formatPrice, formatPriceRange, formatAmount, formatDate, formatDateTime, formatNumber, formatPercentage, getCurrencySymbol, CURRENCY_SYMBOLS, CURRENCY_LOCALES, type PriceMoney, } from './format';
53
57
  export { AUTH_COOKIE_NAME, AUTH_COOKIE_DEFAULTS, type AuthCookieConfig, } from './auth/cookie-config';
58
+ export { LANGUAGE_COOKIE_NAME, LANGUAGE_COOKIE_MAX_AGE, LANGUAGE_HEADER_NAME } from './language/cookie-config';
59
+ export { CURRENCY_COOKIE_NAME, CURRENCY_COOKIE_MAX_AGE, CURRENCY_HEADER_NAME } from './currency/cookie-config';
60
+ export { CART_COOKIE_NAME, CART_COOKIE_MAX_AGE } from './cart/cookie-config';
54
61
  export { matchesRoute, type RouteProtectionConfig } from './auth/routes';
55
62
  export { createSetTokenHandler, createClearTokenHandler } from './auth/handlers';
56
63
  export { createAuthTokenClient, type AuthTokenClient } from './auth/token-client';
64
+ export { storefrontImageLoader, type ImageData, type ImageLoaderParams, } from './image';
57
65
  export { getOperationName } from './client/operation-name';
58
66
  export { hashQuery } from './client/hash';
59
67
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,YAAY,EACZ,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAGpF,OAAO,EACL,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,KAAK,cAAc,GACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,YAAY,EACV,IAAI,EACJ,QAAQ,EACR,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,KAAK,GACN,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,YAAY,EACV,QAAQ,EACR,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,gBAAgB,GACtB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,YAAY,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAGjF,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGlF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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"}
@@ -38,9 +38,14 @@ export { createStorefrontClient } from './client/create-client';
38
38
  // Middleware
39
39
  export { authMiddleware } from './middleware/auth';
40
40
  export { currencyMiddleware } from './middleware/currency';
41
+ export { languageMiddleware } from './middleware/language';
42
+ export { botProtectionMiddleware, BOT_PROTECTION_HEADER, } from './middleware/bot-protection';
41
43
  export { retryMiddleware } from './middleware/retry';
42
44
  export { timeoutMiddleware } from './middleware/timeout';
43
45
  export { errorMiddleware } from './middleware/errors';
46
+ // Bot protection managers (framework-agnostic, DOM APIs)
47
+ export { createBotProtectionManager } from './bot-protection/create-manager';
48
+ export { FallbackBotProtectionManager } from './bot-protection/fallback-manager';
44
49
  // Errors
45
50
  export { StorefrontError, ErrorCodes } from './errors';
46
51
  // Cache strategies
@@ -57,12 +62,20 @@ export { normalizeConnection, } from './helpers/normalize-connection';
57
62
  export { formatPrice, formatPriceRange, formatAmount, formatDate, formatDateTime, formatNumber, formatPercentage, getCurrencySymbol, CURRENCY_SYMBOLS, CURRENCY_LOCALES, } from './format';
58
63
  // Auth cookie config (platform contract)
59
64
  export { AUTH_COOKIE_NAME, AUTH_COOKIE_DEFAULTS, } from './auth/cookie-config';
65
+ // Language config
66
+ export { LANGUAGE_COOKIE_NAME, LANGUAGE_COOKIE_MAX_AGE, LANGUAGE_HEADER_NAME } from './language/cookie-config';
67
+ // Currency config
68
+ export { CURRENCY_COOKIE_NAME, CURRENCY_COOKIE_MAX_AGE, CURRENCY_HEADER_NAME } from './currency/cookie-config';
69
+ // Cart cookie config
70
+ export { CART_COOKIE_NAME, CART_COOKIE_MAX_AGE } from './cart/cookie-config';
60
71
  // Auth route matching
61
72
  export { matchesRoute } from './auth/routes';
62
73
  // Auth cookie handlers (API route factories)
63
74
  export { createSetTokenHandler, createClearTokenHandler } from './auth/handlers';
64
75
  // Auth token client (client-side fetch helpers)
65
76
  export { createAuthTokenClient } from './auth/token-client';
77
+ // Image utilities
78
+ export { storefrontImageLoader, } from './image';
66
79
  // Utilities
67
80
  export { getOperationName } from './client/operation-name';
68
81
  export { hashQuery } from './client/hash';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Language configuration constants — platform contract.
3
+ *
4
+ * Used by:
5
+ * - SDK language store (client-side cookie read/write)
6
+ * - SDK language middleware (X-Lang header)
7
+ * - next-intl middleware `localeCookie.name` (server-side locale detection)
8
+ *
9
+ * Single cookie replaces both next-intl's NEXT_LOCALE and SDK's preferred-language.
10
+ */
11
+ export declare const LANGUAGE_COOKIE_NAME = "preferred-language";
12
+ export declare const LANGUAGE_COOKIE_MAX_AGE: number;
13
+ export declare const LANGUAGE_HEADER_NAME = "X-Lang";
14
+ //# sourceMappingURL=cookie-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-config.d.ts","sourceRoot":"","sources":["../../../src/core/language/cookie-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AACzD,eAAO,MAAM,uBAAuB,QAAqB,CAAC;AAC1D,eAAO,MAAM,oBAAoB,WAAW,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Language configuration constants — platform contract.
3
+ *
4
+ * Used by:
5
+ * - SDK language store (client-side cookie read/write)
6
+ * - SDK language middleware (X-Lang header)
7
+ * - next-intl middleware `localeCookie.name` (server-side locale detection)
8
+ *
9
+ * Single cookie replaces both next-intl's NEXT_LOCALE and SDK's preferred-language.
10
+ */
11
+ export const LANGUAGE_COOKIE_NAME = 'preferred-language';
12
+ export const LANGUAGE_COOKIE_MAX_AGE = 365 * 24 * 60 * 60; // 1 year
13
+ export const LANGUAGE_HEADER_NAME = 'X-Lang';
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Bot protection middleware — vendor-agnostic token injection.
3
+ *
4
+ * Intercepts protected mutations and adds a bot verification token
5
+ * via the X-Bot-Protection-Token header. Token acquisition is delegated
6
+ * to a BotProtectionTokenProvider (EU CAPTCHA, Turnstile, etc.).
7
+ *
8
+ * Fail strategy is per-operation: 'open' = continue without token,
9
+ * 'closed' = throw if token unavailable.
10
+ */
11
+ import type { Middleware } from '../client/types';
12
+ /** Vendor-agnostic token provider interface */
13
+ export interface BotProtectionTokenProvider {
14
+ /**
15
+ * Get a fresh bot protection token.
16
+ * Handles: in-flight deduplication, timeout, singleton script loading.
17
+ *
18
+ * @param options.action - Operation name (e.g. 'CustomerCreate') for action validation
19
+ * @param options.timeoutMs - Timeout in ms (default: 10000)
20
+ * @returns Token string or null if unavailable (adblock, timeout, error)
21
+ */
22
+ execute(options?: {
23
+ action?: string;
24
+ timeoutMs?: number;
25
+ }): Promise<string | null>;
26
+ /** Cleanup widget and script resources */
27
+ destroy(): void;
28
+ }
29
+ /** Single provider config (from shop query) */
30
+ export interface BotProtectionProviderConfig {
31
+ /** Provider identifier: 'eucaptcha' | 'turnstile' | 'recaptcha' | extensible */
32
+ provider: string;
33
+ /** Site key for the bot protection widget */
34
+ siteKey: string;
35
+ /** Script URL — configurable for region-specific / enterprise overrides */
36
+ scriptUrl: string;
37
+ }
38
+ /** Bot protection configuration from shop query */
39
+ export interface BotProtectionConfig {
40
+ /** Primary provider */
41
+ primary: BotProtectionProviderConfig;
42
+ /** Fallback provider (runtime: if primary fails -> fallback -> fail-open) */
43
+ fallback?: BotProtectionProviderConfig | null;
44
+ /** GraphQL operation names requiring verification */
45
+ protectedOperations: string[];
46
+ }
47
+ /** Fail strategy per request */
48
+ export type FailStrategy = 'open' | 'closed';
49
+ export interface BotProtectionMiddlewareOptions {
50
+ /** Token provider instance (manager or fallback chain) */
51
+ tokenProvider: BotProtectionTokenProvider;
52
+ /** GraphQL operation names that require bot protection */
53
+ protectedOperations: string[];
54
+ /** Default fail strategy when token acquisition fails (default: 'open') */
55
+ defaultFailStrategy?: FailStrategy;
56
+ /** Override fail strategy per operation (e.g. CheckoutComplete = closed) */
57
+ failStrategyOverrides?: Record<string, FailStrategy>;
58
+ }
59
+ /** Header name for bot protection token */
60
+ export declare const BOT_PROTECTION_HEADER = "X-Bot-Protection-Token";
61
+ /**
62
+ * Creates bot protection middleware for the SDK pipeline.
63
+ *
64
+ * Only intercepts mutations whose operationName is in protectedOperations.
65
+ * Token is fetched fresh on every call (single-use tokens, retry-safe).
66
+ *
67
+ * Pipeline position: AFTER auth/currency, BEFORE retry/timeout/errors.
68
+ * Retry middleware re-executes the full chain, so each attempt gets a fresh token.
69
+ */
70
+ export declare function botProtectionMiddleware(options: BotProtectionMiddlewareOptions): Middleware;
71
+ //# sourceMappingURL=bot-protection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot-protection.d.ts","sourceRoot":"","sources":["../../../src/core/middleware/bot-protection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlD,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEnF,0CAA0C;IAC1C,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD,+CAA+C;AAC/C,MAAM,WAAW,2BAA2B;IAC1C,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,mDAAmD;AACnD,MAAM,WAAW,mBAAmB;IAClC,uBAAuB;IACvB,OAAO,EAAE,2BAA2B,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC9C,qDAAqD;IACrD,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,gCAAgC;AAChC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAM7C,MAAM,WAAW,8BAA8B;IAC7C,0DAA0D;IAC1D,aAAa,EAAE,0BAA0B,CAAC;IAC1C,0DAA0D;IAC1D,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,2EAA2E;IAC3E,mBAAmB,CAAC,EAAE,YAAY,CAAC;IACnC,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtD;AAMD,2CAA2C;AAC3C,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAM9D;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,UAAU,CA2C3F"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Bot protection middleware — vendor-agnostic token injection.
3
+ *
4
+ * Intercepts protected mutations and adds a bot verification token
5
+ * via the X-Bot-Protection-Token header. Token acquisition is delegated
6
+ * to a BotProtectionTokenProvider (EU CAPTCHA, Turnstile, etc.).
7
+ *
8
+ * Fail strategy is per-operation: 'open' = continue without token,
9
+ * 'closed' = throw if token unavailable.
10
+ */
11
+ import { StorefrontError } from '../errors';
12
+ // ---------------------------------------------------------------------------
13
+ // Constants
14
+ // ---------------------------------------------------------------------------
15
+ /** Header name for bot protection token */
16
+ export const BOT_PROTECTION_HEADER = 'X-Bot-Protection-Token';
17
+ // ---------------------------------------------------------------------------
18
+ // Middleware factory
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Creates bot protection middleware for the SDK pipeline.
22
+ *
23
+ * Only intercepts mutations whose operationName is in protectedOperations.
24
+ * Token is fetched fresh on every call (single-use tokens, retry-safe).
25
+ *
26
+ * Pipeline position: AFTER auth/currency, BEFORE retry/timeout/errors.
27
+ * Retry middleware re-executes the full chain, so each attempt gets a fresh token.
28
+ */
29
+ export function botProtectionMiddleware(options) {
30
+ const { tokenProvider, protectedOperations, defaultFailStrategy = 'open', failStrategyOverrides = {}, } = options;
31
+ const protectedSet = new Set(protectedOperations);
32
+ return async (request, next) => {
33
+ // Only intercept mutations
34
+ if (!request.isMutation)
35
+ return next(request);
36
+ // Only intercept protected operations
37
+ const opName = request.operationName;
38
+ if (!opName || !protectedSet.has(opName)) {
39
+ return next(request);
40
+ }
41
+ // Fetch fresh token — action param enables backend action validation
42
+ const token = await tokenProvider.execute({
43
+ action: opName,
44
+ timeoutMs: 10000,
45
+ });
46
+ if (token) {
47
+ request.headers[BOT_PROTECTION_HEADER] = token;
48
+ }
49
+ else {
50
+ // Fail strategy: open = continue without token, closed = throw
51
+ const strategy = failStrategyOverrides[opName] ?? defaultFailStrategy;
52
+ if (strategy === 'closed') {
53
+ throw new StorefrontError({
54
+ code: 'BOT_PROTECTION_REQUIRED',
55
+ message: 'Bot protection verification failed. Please try again.',
56
+ status: 0,
57
+ });
58
+ }
59
+ // fail-open: continue without token — backend guard may still reject
60
+ }
61
+ return next(request);
62
+ };
63
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"currency.d.ts","sourceRoot":"","sources":["../../../src/core/middleware/currency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GAC3C,UAAU,CAQZ"}
1
+ {"version":3,"file":"currency.d.ts","sourceRoot":"","sources":["../../../src/core/middleware/currency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GAC3C,UAAU,CAQZ"}
@@ -10,11 +10,12 @@
10
10
  * client.use(currencyMiddleware(() => currencyStore.getState().currency));
11
11
  * ```
12
12
  */
13
+ import { CURRENCY_HEADER_NAME } from '../currency/cookie-config';
13
14
  export function currencyMiddleware(getCurrency) {
14
15
  return (request, next) => {
15
16
  const currency = getCurrency();
16
17
  if (currency) {
17
- request.headers['X-Preferred-Currency'] = currency;
18
+ request.headers[CURRENCY_HEADER_NAME] = currency;
18
19
  }
19
20
  return next(request);
20
21
  };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Language middleware — adds X-Lang header.
3
+ *
4
+ * Language is resolved lazily so language switches are reflected immediately.
5
+ * CRITICAL: does NOT send header when language=null (store not yet initialized)
6
+ * — without this, backend returns default language, React Query caches it,
7
+ * and after setLanguage() the cache is stale.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { languageMiddleware } from '@doswiftly/storefront-sdk';
12
+ *
13
+ * client.use(languageMiddleware(() => languageStore.getState().language));
14
+ * ```
15
+ */
16
+ import type { Middleware } from '../client/types';
17
+ export declare function languageMiddleware(getLanguage: () => string | null | undefined): Middleware;
18
+ //# sourceMappingURL=language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../../src/core/middleware/language.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GAC3C,UAAU,CAQZ"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Language middleware — adds X-Lang header.
3
+ *
4
+ * Language is resolved lazily so language switches are reflected immediately.
5
+ * CRITICAL: does NOT send header when language=null (store not yet initialized)
6
+ * — without this, backend returns default language, React Query caches it,
7
+ * and after setLanguage() the cache is stale.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { languageMiddleware } from '@doswiftly/storefront-sdk';
12
+ *
13
+ * client.use(languageMiddleware(() => languageStore.getState().language));
14
+ * ```
15
+ */
16
+ import { LANGUAGE_HEADER_NAME } from '../language/cookie-config';
17
+ export function languageMiddleware(getLanguage) {
18
+ return (request, next) => {
19
+ const language = getLanguage();
20
+ if (language) {
21
+ request.headers[LANGUAGE_HEADER_NAME] = language;
22
+ }
23
+ return next(request);
24
+ };
25
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Bot protection React context.
3
+ *
4
+ * Provides access to the BotProtectionTokenProvider manager
5
+ * for the useBotProtection() escape hatch hook.
6
+ */
7
+ import type { BotProtectionTokenProvider } from '../../core/middleware/bot-protection';
8
+ export interface BotProtectionContextValue {
9
+ manager: BotProtectionTokenProvider | null;
10
+ }
11
+ export declare const BotProtectionContext: import("react").Context<BotProtectionContextValue | null>;
12
+ //# sourceMappingURL=bot-protection-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot-protection-context.d.ts","sourceRoot":"","sources":["../../../src/react/bot-protection/bot-protection-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAEvF,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,0BAA0B,GAAG,IAAI,CAAC;CAC5C;AAED,eAAO,MAAM,oBAAoB,2DAAwD,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Bot protection React context.
3
+ *
4
+ * Provides access to the BotProtectionTokenProvider manager
5
+ * for the useBotProtection() escape hatch hook.
6
+ */
7
+ 'use client';
8
+ import { createContext } from 'react';
9
+ export const BotProtectionContext = createContext(null);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * BotProtectionWidget — invisible React wrapper that mounts the bot protection manager.
3
+ *
4
+ * Renders a hidden div and mounts/unmounts the manager lifecycle.
5
+ * Triggers lazy script preload on mount.
6
+ */
7
+ import type { BotProtectionTokenProvider } from '../../core/middleware/bot-protection';
8
+ interface BotProtectionWidgetProps {
9
+ manager: BotProtectionTokenProvider | null;
10
+ }
11
+ export declare function BotProtectionWidget({ manager }: BotProtectionWidgetProps): import("react/jsx-runtime").JSX.Element | null;
12
+ export {};
13
+ //# sourceMappingURL=bot-protection-widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot-protection-widget.d.ts","sourceRoot":"","sources":["../../../src/react/bot-protection/bot-protection-widget.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAGvF,UAAU,wBAAwB;IAChC,OAAO,EAAE,0BAA0B,GAAG,IAAI,CAAC;CAC5C;AAED,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,EAAE,wBAAwB,kDA4BxE"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * BotProtectionWidget — invisible React wrapper that mounts the bot protection manager.
3
+ *
4
+ * Renders a hidden div and mounts/unmounts the manager lifecycle.
5
+ * Triggers lazy script preload on mount.
6
+ */
7
+ 'use client';
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { useEffect, useRef } from 'react';
10
+ export function BotProtectionWidget({ manager }) {
11
+ const containerRef = useRef(null);
12
+ const mountedRef = useRef(false);
13
+ useEffect(() => {
14
+ if (!manager || !containerRef.current || mountedRef.current)
15
+ return;
16
+ mountedRef.current = true;
17
+ // Trigger lazy script preload + mount container
18
+ const mgr = manager;
19
+ if (typeof mgr.loadScript === 'function') {
20
+ mgr.loadScript().catch(() => {
21
+ // Script load failure is handled gracefully in execute()
22
+ });
23
+ }
24
+ if (typeof mgr.mount === 'function') {
25
+ mgr.mount(containerRef.current);
26
+ }
27
+ return () => {
28
+ mountedRef.current = false;
29
+ };
30
+ }, [manager]);
31
+ if (!manager)
32
+ return null;
33
+ return _jsx("div", { ref: containerRef, style: { display: 'none' }, "aria-hidden": "true" });
34
+ }
@@ -10,11 +10,14 @@
10
10
  export declare function getCookie(name: string): string | null;
11
11
  /**
12
12
  * Set cookie (client-side only).
13
+ *
14
+ * `secure` defaults to auto-detect from `location.protocol` (true on HTTPS).
13
15
  */
14
16
  export declare function setCookie(name: string, value: string, options?: {
15
17
  maxAge?: number;
16
18
  path?: string;
17
19
  sameSite?: string;
20
+ secure?: boolean;
18
21
  }): void;
19
22
  /**
20
23
  * Delete cookie (client-side only).
@@ -25,4 +28,18 @@ export declare function deleteCookie(name: string, path?: string): void;
25
28
  * Falls back to document.cookie on client.
26
29
  */
27
30
  export declare function getCurrencyFromCookieAsync(): Promise<string | null>;
31
+ /**
32
+ * Get cart ID from cookie (async — works with Next.js cookies()).
33
+ * Falls back to document.cookie on client.
34
+ *
35
+ * Use in Server Components for SSR cart badge:
36
+ * ```typescript
37
+ * const cartId = await getCartIdFromCookieAsync();
38
+ * if (cartId) {
39
+ * const cart = await fetchCart(cartId);
40
+ * // Render cart badge with real totalQuantity — no skeleton needed
41
+ * }
42
+ * ```
43
+ */
44
+ export declare function getCartIdFromCookieAsync(): Promise<string | null>;
28
45
  //# sourceMappingURL=cookies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/react/cookies.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClE,IAAI,CAIN;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,IAAI,CAG3D;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYzE"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/react/cookies.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACpF,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,IAAI,CAG3D;AAKD;;;GAGG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYzE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYvE"}