@doswiftly/storefront-sdk 20.2.0 → 21.0.1

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 (41) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +776 -529
  3. package/dist/core/auth/handlers.d.ts +10 -9
  4. package/dist/core/auth/handlers.d.ts.map +1 -1
  5. package/dist/core/auth/handlers.js +10 -9
  6. package/dist/core/auth/session-events.d.ts +2 -2
  7. package/dist/core/auth/session-events.js +2 -2
  8. package/dist/core/cart/cart-client.d.ts +23 -24
  9. package/dist/core/cart/cart-client.d.ts.map +1 -1
  10. package/dist/core/cart/cart-client.js +24 -25
  11. package/dist/core/generated/operation-types.d.ts +102 -108
  12. package/dist/core/generated/operation-types.d.ts.map +1 -1
  13. package/dist/core/middleware/session-retry.d.ts +5 -6
  14. package/dist/core/middleware/session-retry.d.ts.map +1 -1
  15. package/dist/core/middleware/session-retry.js +7 -8
  16. package/dist/core/operations/auth.d.ts.map +1 -1
  17. package/dist/core/operations/auth.js +4 -0
  18. package/dist/core/operations/cart.d.ts +11 -10
  19. package/dist/core/operations/cart.d.ts.map +1 -1
  20. package/dist/core/operations/cart.js +14 -11
  21. package/dist/react/components/PaymentInstrumentSection.d.ts +24 -24
  22. package/dist/react/components/PaymentInstrumentSection.d.ts.map +1 -1
  23. package/dist/react/components/PaymentInstrumentSection.js +15 -15
  24. package/dist/react/components/PaymentInstrumentTile.d.ts +19 -20
  25. package/dist/react/components/PaymentInstrumentTile.d.ts.map +1 -1
  26. package/dist/react/components/PaymentInstrumentTile.js +15 -16
  27. package/dist/react/helpers/browser-data.d.ts +30 -33
  28. package/dist/react/helpers/browser-data.d.ts.map +1 -1
  29. package/dist/react/helpers/browser-data.js +26 -29
  30. package/dist/react/hooks/use-cart-manager.d.ts +1 -1
  31. package/dist/react/hooks/use-cart-manager.js +1 -1
  32. package/dist/react/hooks/use-cart.d.ts +2 -2
  33. package/dist/react/hooks/use-cart.js +3 -3
  34. package/dist/react/hooks/use-session-expired.d.ts +6 -5
  35. package/dist/react/hooks/use-session-expired.d.ts.map +1 -1
  36. package/dist/react/hooks/use-session-expired.js +6 -5
  37. package/dist/react/stores/auth.store.d.ts.map +1 -1
  38. package/dist/react/stores/auth.store.js +13 -10
  39. package/dist/react/stores/cart.store.d.ts +1 -1
  40. package/dist/react/stores/cart.store.js +1 -1
  41. package/package.json +1 -1
@@ -1,36 +1,36 @@
1
1
  /**
2
2
  * `getBrowserDataForPayment()` — collects browser context required by PSD2/3DS2
3
- * authentication flows (card-on-file z 3DS challenge, BLIK confirmation,
4
- * Apple/Google Pay z risk scoring).
3
+ * authentication flows (card-on-file with a 3DS challenge, BLIK confirmation,
4
+ * Apple/Google Pay with risk scoring).
5
5
  *
6
- * **Browser-only** — throws gdy `typeof window === 'undefined'` (server-side
7
- * rendering). Caller MUSI gate'ować call w useEffect / event handler / browser
8
- * code path. NEVER call this w Server Component lub Route Handler.
6
+ * **Browser-only** — throws when `typeof window === 'undefined'` (server-side
7
+ * rendering). Callers MUST gate the call inside a useEffect / event handler /
8
+ * browser-only code path. NEVER call this in a Server Component or Route Handler.
9
9
  *
10
- * Wartości pochodzą z standard Web APIs:
10
+ * Values come from standard Web APIs:
11
11
  * - `userAgent` — `navigator.userAgent`.
12
12
  * - `language` — `navigator.language` (BCP 47, fallback `en-US`).
13
13
  * - `screen{Width,Height}` — `window.screen.{width,height}`.
14
14
  * - `colorDepth` — `window.screen.colorDepth`.
15
15
  * - `timezoneOffset` — `new Date().getTimezoneOffset()` (signed integer, minutes,
16
- * reverse signed per ECMA: dodatnie = behind UTC, ujemne = ahead).
17
- * - `javaEnabled` — `navigator.javaEnabled?.()` (deprecated ale wymagane PSD2/EMV
18
- * specification; fallback `false` gdy browser nie expose'uje).
19
- * - `acceptHeader` — NIE dostępne client-side (`navigator` nie expose'uje request
20
- * headers). Caller passes z server context lub omits (gateway-dependent
21
- * requirement). Helper zwraca undefined.
16
+ * reverse signed per ECMA: positive = behind UTC, negative = ahead of UTC).
17
+ * - `javaEnabled` — `navigator.javaEnabled?.()` (deprecated but required by the
18
+ * PSD2/EMV specification; falls back to `false` when the browser does not
19
+ * expose it).
20
+ * - `acceptHeader` NOT available client-side (`navigator` does not expose
21
+ * request headers). Callers pass it from server context or omit it
22
+ * (gateway-dependent requirement). The helper returns undefined.
22
23
  *
23
- * Shape matches PSD2/3DS2 BrowserData specification (EMVCo) adapter na backend
24
- * `IPaymentProvider.createPayment` może merge wprost do gateway-specific body
25
- * (Adyen `browserInfo`, Stripe `payment_method_data.billing_details.browser_info`,
26
- * Mollie `cardToken` z 3DS lookup).
24
+ * The shape matches the PSD2/3DS2 BrowserData specification (EMVCo), so it can
25
+ * be merged into gateway-specific request bodies (gateway-specific field names
26
+ * vary).
27
27
  *
28
28
  * @example
29
29
  * ```tsx
30
- * // W event handler (browser-only):
30
+ * // In an event handler (browser-only):
31
31
  * function handleCheckoutSubmit() {
32
32
  * const browserData = getBrowserDataForPayment();
33
- * await cart.createPayment({ ..., browserData });
33
+ * // pass to your payment integration where required
34
34
  * }
35
35
  *
36
36
  * // SSR-safe wrap:
@@ -39,15 +39,11 @@
39
39
  * ...
40
40
  * }
41
41
  * ```
42
- *
43
- * Added by payment-instrument-preselection-advanced sub-sprint Adv-2 Req 9.5
44
- * (carry-over z Adv-1 plan — moved here as standalone utility, no backend
45
- * mutation impact yet — Adv-3 będzie consumer'em w `paymentCreate` input).
46
42
  */
47
43
  /**
48
- * Throw'd gdy helper wywołany w SSR context (Server Component, Route Handler,
49
- * Node bez JSDOM). Caller MUSI guard'ować przez `typeof window` check albo
50
- * wywołać tylko w event handler / `useEffect`.
44
+ * Thrown when the helper is called in an SSR context (Server Component, Route
45
+ * Handler, Node without JSDOM). Callers MUST guard with a `typeof window` check
46
+ * or call it only inside an event handler / `useEffect`.
51
47
  */
52
48
  export class BrowserDataNotAvailableError extends Error {
53
49
  constructor() {
@@ -59,11 +55,12 @@ export function getBrowserDataForPayment() {
59
55
  if (typeof window === 'undefined' || typeof navigator === 'undefined' || typeof window.screen === 'undefined') {
60
56
  throw new BrowserDataNotAvailableError();
61
57
  }
62
- // `navigator.javaEnabled` jest deprecated ale wciąż obecny w major browsers — guard
63
- // dla future removal. Falsy fallback gdy missing (PSD2 spec wymaga boolean, not undefined).
58
+ // `navigator.javaEnabled` is deprecated but still present in major browsers — guard
59
+ // against future removal. Falls back to `false` when missing (the PSD2 spec requires
60
+ // a boolean, not undefined).
64
61
  const javaEnabled = typeof navigator.javaEnabled === 'function' ? Boolean(navigator.javaEnabled()) : false;
65
- // `Intl.DateTimeFormat` jest dostępny we wszystkich modern browsers — optional capture
66
- // dla gateways które wymagają IANA name zamiast offset (np. Adyen).
62
+ // `Intl.DateTimeFormat` is available in all modern browsers — optional capture for
63
+ // gateways that require the IANA name instead of the numeric offset.
67
64
  let timezone;
68
65
  try {
69
66
  timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
@@ -62,7 +62,7 @@
62
62
  * function CartUI() {
63
63
  * const { addItem, onExpired } = useCartManager();
64
64
  *
65
- * useEffect(() => onExpired(() => toast('Koszyk wygasł, dodaj produkty ponownie')), [onExpired]);
65
+ * useEffect(() => onExpired(() => toast('Your cart expired please add the items again')), [onExpired]);
66
66
  *
67
67
  * return <button onClick={() => addItem([{ variantId, quantity: 1 }])}>Add</button>;
68
68
  * }
@@ -62,7 +62,7 @@
62
62
  * function CartUI() {
63
63
  * const { addItem, onExpired } = useCartManager();
64
64
  *
65
- * useEffect(() => onExpired(() => toast('Koszyk wygasł, dodaj produkty ponownie')), [onExpired]);
65
+ * useEffect(() => onExpired(() => toast('Your cart expired please add the items again')), [onExpired]);
66
66
  *
67
67
  * return <button onClick={() => addItem([{ variantId, quantity: 1 }])}>Add</button>;
68
68
  * }
@@ -9,8 +9,8 @@
9
9
  * UIs need.
10
10
  *
11
11
  * State management follows the platform's store pattern: a vanilla Zustand
12
- * store is created per hook mount via `useMemo` (component-scoped, no
13
- * module-level singleton — Inv-3 of the SDK), and React subscribes through
12
+ * store is created per hook mount via `useMemo` (stores are component-scoped,
13
+ * never module-level singletons), and React subscribes through
14
14
  * `useStore`. Changing `cartId` recreates the store; refetches are explicit
15
15
  * (`refetch()` or any mutation triggers one).
16
16
  *
@@ -9,8 +9,8 @@
9
9
  * UIs need.
10
10
  *
11
11
  * State management follows the platform's store pattern: a vanilla Zustand
12
- * store is created per hook mount via `useMemo` (component-scoped, no
13
- * module-level singleton — Inv-3 of the SDK), and React subscribes through
12
+ * store is created per hook mount via `useMemo` (stores are component-scoped,
13
+ * never module-level singletons), and React subscribes through
14
14
  * `useStore`. Changing `cartId` recreates the store; refetches are explicit
15
15
  * (`refetch()` or any mutation triggers one).
16
16
  *
@@ -84,7 +84,7 @@ export function useCart(cartId, options = {}) {
84
84
  const { autoFetch = true, initialCart } = options;
85
85
  // Recreate the store when `cartId` or the underlying client changes. The
86
86
  // useMemo dependency list captures store identity (component-scoped, not
87
- // module-level — Inv-3). Mutations capture the store instance for stable
87
+ // module-level). Mutations capture the store instance for stable
88
88
  // references via the api object.
89
89
  const api = useMemo(() => createServerCartStore({ cartClient, cartId, initialCart }),
90
90
  // initialCart deliberately excluded — it only seeds the FIRST mount; we do
@@ -2,14 +2,15 @@
2
2
  * useSessionExpired — subscribe to the global session-expired signal.
3
3
  *
4
4
  * Fired when the SDK can no longer keep the customer session alive: a proactive
5
- * refresh failed on tab wake (R6.3), or a reactive refresh after a 401 also
6
- * failed (R2.4). Use once near the app root to react globally — show a notice
7
- * and redirect to sign-in (R14.2). No-op outside `StorefrontProvider`.
5
+ * refresh failed on tab wake, or a reactive refresh after a 401 also failed.
6
+ * Use once near the app root to react globally — show a notice and redirect
7
+ * to sign-in. No-op outside `StorefrontProvider`.
8
8
  */
9
9
  import type { SessionExpiredEmitter, SessionExpiredEvent } from '../../core/auth/session-events';
10
10
  /**
11
- * Context carrying the provider-scoped session-expired emitter. Created in
12
- * `StorefrontProvider` via `useRef` (Inv-3 — never a module-level singleton).
11
+ * Context carrying the provider-scoped session-expired emitter. Created per
12
+ * provider mount in `StorefrontProvider` via `useRef` — never a module-level
13
+ * singleton.
13
14
  */
14
15
  export declare const SessionExpiredContext: import("react").Context<SessionExpiredEmitter | null>;
15
16
  export declare function useSessionExpired(listener: (event: SessionExpiredEvent) => void): void;
@@ -1 +1 @@
1
- {"version":3,"file":"use-session-expired.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-session-expired.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAEjG;;;GAGG;AACH,eAAO,MAAM,qBAAqB,uDAAoD,CAAC;AAEvF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAUtF"}
1
+ {"version":3,"file":"use-session-expired.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-session-expired.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAEjG;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,uDAAoD,CAAC;AAEvF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAUtF"}
@@ -2,15 +2,16 @@
2
2
  * useSessionExpired — subscribe to the global session-expired signal.
3
3
  *
4
4
  * Fired when the SDK can no longer keep the customer session alive: a proactive
5
- * refresh failed on tab wake (R6.3), or a reactive refresh after a 401 also
6
- * failed (R2.4). Use once near the app root to react globally — show a notice
7
- * and redirect to sign-in (R14.2). No-op outside `StorefrontProvider`.
5
+ * refresh failed on tab wake, or a reactive refresh after a 401 also failed.
6
+ * Use once near the app root to react globally — show a notice and redirect
7
+ * to sign-in. No-op outside `StorefrontProvider`.
8
8
  */
9
9
  'use client';
10
10
  import { createContext, useContext, useEffect, useRef } from 'react';
11
11
  /**
12
- * Context carrying the provider-scoped session-expired emitter. Created in
13
- * `StorefrontProvider` via `useRef` (Inv-3 — never a module-level singleton).
12
+ * Context carrying the provider-scoped session-expired emitter. Created per
13
+ * provider mount in `StorefrontProvider` via `useRef` — never a module-level
14
+ * singleton.
14
15
  */
15
16
  export const SessionExpiredContext = createContext(null);
16
17
  export function useSessionExpired(listener) {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/auth.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IAExB,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IAGnB,OAAO,EAAE,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjG,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB;;;;OAIG;IACH,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACzD,UAAU,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,eAAe,GAAI,UAAU,sBAAsB;;;;;sBAyExC,YAAY,GAAG,IAAI;6BACZ,OAAO;;;;;;;;sBADd,YAAY,GAAG,IAAI;6BACZ,OAAO;;;CAUnC,CAAC"}
1
+ {"version":3,"file":"auth.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/auth.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IAExB,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IAGnB,OAAO,EAAE,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjG,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB;;;;OAIG;IACH,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACzD,UAAU,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,eAAe,GAAI,UAAU,sBAAsB;;;;;sBA4ExC,YAAY,GAAG,IAAI;6BACZ,OAAO;;;;;;;;sBADd,YAAY,GAAG,IAAI;6BACZ,OAAO;;;CAUnC,CAAC"}
@@ -42,10 +42,11 @@ export const createAuthStore = (options) => createStore()(persist((set) => ({
42
42
  setLoading: (isLoading) => set({ isLoading }),
43
43
  }), {
44
44
  name: AUTH_STORAGE_KEY,
45
- version: 3, // v3 (Iteracja 2 — XSS fix): accessToken DROP'owany z localStorage
46
- // persistence. Token żyje tylko w-memory + httpOnly cookie (browser auto-sent).
47
- // Non-browser klienci (mobile native, server-to-server) ustawiają token explicit
48
- // przez setAuth() — nigdy nie persistowany w localStorage SDK.
45
+ version: 3, // v3 (XSS hardening): accessToken dropped from localStorage
46
+ // persistence. The token lives only in memory + the httpOnly cookie
47
+ // (browser auto-sent). Non-browser clients (mobile native, server-to-server)
48
+ // set the token explicitly via setAuth() — it is never persisted to the
49
+ // SDK's localStorage slice.
49
50
  partialize: (state) => ({
50
51
  customer: state.customer,
51
52
  isAuthenticated: state.isAuthenticated,
@@ -63,18 +64,20 @@ export const createAuthStore = (options) => createStore()(persist((set) => ({
63
64
  return {
64
65
  ...currentState,
65
66
  customer: persisted.customer ?? currentState.customer,
66
- // accessToken NIE persistowany w localStorage (Inv-5 XSS hardening) — spread
67
- // `...currentState` propaguje wartość z factory: `null` (default) lub seed
68
- // z `options.initialAccessToken` gdy konsumer podał token server-side.
67
+ // accessToken is never persisted to localStorage (XSS hardening) — the
68
+ // `...currentState` spread propagates the factory value: `null` (default)
69
+ // or the seed from `options.initialAccessToken` when the consumer provided
70
+ // a server-side token.
69
71
  // Server cookie is the authority — never let stale localStorage override it.
70
72
  isAuthenticated: currentState.isAuthenticated,
71
73
  };
72
74
  },
73
75
  migrate: (persistedState, version) => {
74
76
  if (version < 3) {
75
- // v1→v2: Turbopack duplication cleanup; v2→v3: XSS fix — accessToken usunięty
76
- // z localStorage. Po migracji store start fresh, użytkownik re-auth przez
77
- // cookie hydration (BFF /api/auth/whoami) lub login flow.
77
+ // v1→v2: Turbopack duplication cleanup; v2→v3: XSS hardening — accessToken
78
+ // removed from localStorage. After the migration the store starts fresh;
79
+ // the user re-authenticates via cookie hydration (BFF /api/auth/whoami)
80
+ // or the login flow.
78
81
  return { customer: null, isAuthenticated: false };
79
82
  }
80
83
  return persistedState;
@@ -37,7 +37,7 @@
37
37
  *
38
38
  * const store = createCartStore({
39
39
  * getActions: () => actions,
40
- * onExpired: (e) => toast.error('Koszyk wygasł, dodaj produkty ponownie'),
40
+ * onExpired: (e) => toast.error('Your cart expired please add the items again'),
41
41
  * });
42
42
  * ```
43
43
  */
@@ -37,7 +37,7 @@
37
37
  *
38
38
  * const store = createCartStore({
39
39
  * getActions: () => actions,
40
- * onExpired: (e) => toast.error('Koszyk wygasł, dodaj produkty ponownie'),
40
+ * onExpired: (e) => toast.error('Your cart expired please add the items again'),
41
41
  * });
42
42
  * ```
43
43
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doswiftly/storefront-sdk",
3
- "version": "20.2.0",
3
+ "version": "21.0.1",
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
  "sideEffects": false,