@doswiftly/storefront-sdk 21.0.1 → 22.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +83 -0
- package/dist/core/generated/operation-types.d.ts +2 -2
- package/dist/core/generated/operation-types.d.ts.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -0
- package/dist/core/middleware/forwarded-ip.d.ts +82 -0
- package/dist/core/middleware/forwarded-ip.d.ts.map +1 -0
- package/dist/core/middleware/forwarded-ip.js +109 -0
- package/dist/core/referral/cookie-config.d.ts +56 -0
- package/dist/core/referral/cookie-config.d.ts.map +1 -0
- package/dist/core/referral/cookie-config.js +83 -0
- package/dist/react/hooks/use-referral-capture.d.ts +9 -0
- package/dist/react/hooks/use-referral-capture.d.ts.map +1 -0
- package/dist/react/hooks/use-referral-capture.js +40 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -1
- package/dist/react/referral.d.ts +53 -0
- package/dist/react/referral.d.ts.map +1 -0
- package/dist/react/referral.js +51 -0
- package/dist/react/server/cookie-readers.d.ts +7 -0
- package/dist/react/server/cookie-readers.d.ts.map +1 -1
- package/dist/react/server/cookie-readers.js +10 -0
- package/dist/react/server/get-storefront-client.d.ts +19 -1
- package/dist/react/server/get-storefront-client.d.ts.map +1 -1
- package/dist/react/server/get-storefront-client.js +36 -2
- package/dist/react/server/index.d.ts +1 -1
- package/dist/react/server/index.d.ts.map +1 -1
- package/dist/react/server/index.js +2 -2
- package/package.json +1 -1
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { CART_COOKIE_NAME, parseCartCookieValue, } from '../../core/cart/cookie-config';
|
|
26
26
|
import { CURRENCY_COOKIE_NAME } from '../../core/currency/cookie-config';
|
|
27
|
+
import { REFERRAL_COOKIE_NAME } from '../../core/referral/cookie-config';
|
|
27
28
|
import { getCookie } from '../cookies';
|
|
28
29
|
/**
|
|
29
30
|
* Read a cookie server-first: the request cookies via `next/headers` in a Server
|
|
@@ -71,3 +72,12 @@ export async function readCartCredentials() {
|
|
|
71
72
|
export async function readCurrencyCookie() {
|
|
72
73
|
return readCookieIsomorphic(CURRENCY_COOKIE_NAME);
|
|
73
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Read the first-party `referral-code` cookie (server-first, client fallback) —
|
|
77
|
+
* the referral code captured when the visitor landed through a referral share
|
|
78
|
+
* link. Useful for SSR-rendered signup forms that pre-fill the code field;
|
|
79
|
+
* pass it as `customerSignup(input: { referralCode })`.
|
|
80
|
+
*/
|
|
81
|
+
export async function readReferralCodeCookie() {
|
|
82
|
+
return readCookieIsomorphic(REFERRAL_COOKIE_NAME);
|
|
83
|
+
}
|
|
@@ -40,11 +40,29 @@ export interface ServerClientOptions extends Omit<StorefrontClientConfig, 'middl
|
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
42
|
middleware?: Middleware[];
|
|
43
|
+
/**
|
|
44
|
+
* OPTIONAL override for the buyer-IP source. Forwarded-IP signing is
|
|
45
|
+
* auto-configured: by default the SDK reads the request's `cf-connecting-ip`
|
|
46
|
+
* via `next/headers` (a server-rendered storefront would otherwise collapse
|
|
47
|
+
* every buyer onto its own server IP for rate limiting). Provide this only for
|
|
48
|
+
* non-Next server runtimes where `next/headers` is unavailable. May be async.
|
|
49
|
+
* Server-side only.
|
|
50
|
+
*/
|
|
51
|
+
getBuyerIp?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
52
|
+
/**
|
|
53
|
+
* OPTIONAL override for the forwarded-IP signing secret. By default it is read
|
|
54
|
+
* from `process.env.DOSWIFTLY_FORWARDED_IP_SECRET`, set in your DoSwiftly
|
|
55
|
+
* deployment environment. Provide this getter only to override the env source —
|
|
56
|
+
* e.g. a runtime that does not expose the secret on `process.env`. Lazy getter —
|
|
57
|
+
* a rotated secret is picked up without rebuilding the client. NEVER expose this
|
|
58
|
+
* to the browser. Sync or async.
|
|
59
|
+
*/
|
|
60
|
+
getForwardedIpSecret?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
43
61
|
}
|
|
44
62
|
/**
|
|
45
63
|
* Create a StorefrontClient for server-side use.
|
|
46
64
|
*
|
|
47
|
-
* Includes default middleware: retry → timeout → errors.
|
|
65
|
+
* Includes default middleware: forwarded-IP → retry → timeout → errors.
|
|
48
66
|
* Does NOT include auth/currency middleware (server has no Zustand stores).
|
|
49
67
|
* Pass headers via config.defaultHeaders or getHeaders option.
|
|
50
68
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-storefront-client.d.ts","sourceRoot":"","sources":["../../../src/react/server/get-storefront-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"get-storefront-client.d.ts","sourceRoot":"","sources":["../../../src/react/server/get-storefront-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEpG,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,YAAY,CAAC;IACrF;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;IAE1B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAElF;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC7F;AAqBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CA4BlF"}
|
|
@@ -23,18 +23,52 @@ import { createStorefrontClient } from '../../core/client/create-client';
|
|
|
23
23
|
import { retryMiddleware } from '../../core/middleware/retry';
|
|
24
24
|
import { timeoutMiddleware } from '../../core/middleware/timeout';
|
|
25
25
|
import { errorMiddleware } from '../../core/middleware/errors';
|
|
26
|
+
import { forwardedIpMiddleware } from '../../core/middleware/forwarded-ip';
|
|
27
|
+
/**
|
|
28
|
+
* Default buyer-IP source: the request's `cf-connecting-ip` header, read via
|
|
29
|
+
* `next/headers` (the same dynamic-import pattern used to read request cookies — a
|
|
30
|
+
* graceful no-op outside a Next request scope or in runtimes without
|
|
31
|
+
* `next/headers`). Override via `getBuyerIp` for other server frameworks.
|
|
32
|
+
*/
|
|
33
|
+
async function readCfConnectingIp() {
|
|
34
|
+
try {
|
|
35
|
+
const { headers } = await import('next/headers');
|
|
36
|
+
const store = await headers();
|
|
37
|
+
// Prefer a forwarded client-IP header when present: if the request was
|
|
38
|
+
// proxied, the direct `cf-connecting-ip` is the proxy's address while this
|
|
39
|
+
// header carries the original client IP. Fall back to the direct connection IP.
|
|
40
|
+
return store.get('x-doswiftly-client-ip') ?? store.get('cf-connecting-ip');
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
26
46
|
/**
|
|
27
47
|
* Create a StorefrontClient for server-side use.
|
|
28
48
|
*
|
|
29
|
-
* Includes default middleware: retry → timeout → errors.
|
|
49
|
+
* Includes default middleware: forwarded-IP → retry → timeout → errors.
|
|
30
50
|
* Does NOT include auth/currency middleware (server has no Zustand stores).
|
|
31
51
|
* Pass headers via config.defaultHeaders or getHeaders option.
|
|
32
52
|
*/
|
|
33
53
|
export function getStorefrontClient(options) {
|
|
34
|
-
const { middleware: customMiddleware = [], ...config } = options;
|
|
54
|
+
const { middleware: customMiddleware = [], getBuyerIp, getForwardedIpSecret, ...config } = options;
|
|
55
|
+
// Forward the real buyer IP for per-buyer rate limiting — fully self-configured,
|
|
56
|
+
// nothing for the storefront to wire. Buyer IP defaults to the request's
|
|
57
|
+
// `cf-connecting-ip` (via next/headers); the signing secret defaults to
|
|
58
|
+
// `process.env.DOSWIFTLY_FORWARDED_IP_SECRET` (set in the DoSwiftly deployment
|
|
59
|
+
// environment). The slug comes from the `X-Shop-Slug` header the client already
|
|
60
|
+
// sends, so the
|
|
61
|
+
// signed value matches what the backend verifies. The middleware signs ONLY when
|
|
62
|
+
// BOTH a buyer IP and a secret resolve at request time — so with no secret
|
|
63
|
+
// configured (or outside a Next request) it is an inert pass-through. Both
|
|
64
|
+
// getters can be overridden for non-Next runtimes.
|
|
65
|
+
const resolveBuyerIp = getBuyerIp ?? readCfConnectingIp;
|
|
66
|
+
const resolveSecret = getForwardedIpSecret ??
|
|
67
|
+
(() => (typeof process !== 'undefined' ? process.env?.DOSWIFTLY_FORWARDED_IP_SECRET : undefined));
|
|
35
68
|
return createStorefrontClient({
|
|
36
69
|
...config,
|
|
37
70
|
middleware: [
|
|
71
|
+
forwardedIpMiddleware({ getBuyerIp: resolveBuyerIp, getSecret: resolveSecret }),
|
|
38
72
|
...customMiddleware,
|
|
39
73
|
retryMiddleware({ maxRetries: 2 }),
|
|
40
74
|
timeoutMiddleware({ timeout: 10000 }), // Server-side: 10s timeout
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { getStorefrontClient, type ServerClientOptions } from './get-storefront-client';
|
|
2
2
|
export { createStorefrontAuthRoute, type StorefrontAuthRouteOptions, type StorefrontAuthRouteHandlers, } from './create-storefront-auth-route';
|
|
3
3
|
export { getInitialAuth, type InitialAuth } from './get-initial-auth';
|
|
4
|
-
export { readCartIdCookie, readCartCredentials, readCurrencyCookie } from './cookie-readers';
|
|
4
|
+
export { readCartIdCookie, readCartCredentials, readCurrencyCookie, readReferralCodeCookie } from './cookie-readers';
|
|
5
5
|
export { serverCartSecretMiddleware } from '../../core/middleware/cart-secret';
|
|
6
6
|
export { trustedForwardedHostValidator, originAllowlistValidator, type OriginValidator, type OriginValidatorContext, } from '../../core/auth/handlers';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGxF,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,GACjC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGxF,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,GACjC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAIrH,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAG/E,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,EACxB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC"}
|
|
@@ -3,8 +3,8 @@ export { getStorefrontClient } from './get-storefront-client';
|
|
|
3
3
|
export { createStorefrontAuthRoute, } from './create-storefront-auth-route';
|
|
4
4
|
// Server-only cold-start auth seed from the first-party cookies.
|
|
5
5
|
export { getInitialAuth } from './get-initial-auth';
|
|
6
|
-
// Server-first readers for the readable first-party cookies (cart-id, currency).
|
|
7
|
-
export { readCartIdCookie, readCartCredentials, readCurrencyCookie } from './cookie-readers';
|
|
6
|
+
// Server-first readers for the readable first-party cookies (cart-id, currency, referral).
|
|
7
|
+
export { readCartIdCookie, readCartCredentials, readCurrencyCookie, readReferralCodeCookie } from './cookie-readers';
|
|
8
8
|
// Server cart-secret middleware — prepend to `getStorefrontClient({ middleware })`
|
|
9
9
|
// with `await readCartCredentials()` so SSR / edge cart reads carry the secret.
|
|
10
10
|
export { serverCartSecretMiddleware } from '../../core/middleware/cart-secret';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doswiftly/storefront-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "22.1.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
|
"sideEffects": false,
|