@salesforce/storefront-next-runtime 0.4.2 → 1.0.0-alpha.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 (87) hide show
  1. package/README.md +9 -3
  2. package/dist/ComponentContext.js +199 -4
  3. package/dist/ComponentContext.js.map +1 -1
  4. package/dist/DesignComponent.js +2 -2
  5. package/dist/DesignRegion.js +2 -2
  6. package/dist/RegionContext.js +9 -0
  7. package/dist/RegionContext.js.map +1 -0
  8. package/dist/component.types.d.ts +1 -1
  9. package/dist/config.d.ts +34 -221
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +35 -116
  12. package/dist/config.js.map +1 -1
  13. package/dist/data-store.d.ts +185 -15
  14. package/dist/data-store.d.ts.map +1 -1
  15. package/dist/data-store.js +412 -10
  16. package/dist/data-store.js.map +1 -1
  17. package/dist/defaults.d.ts +106 -0
  18. package/dist/defaults.d.ts.map +1 -0
  19. package/dist/defaults.js +67 -0
  20. package/dist/defaults.js.map +1 -0
  21. package/dist/design-data.d.ts +238 -356
  22. package/dist/design-data.d.ts.map +1 -1
  23. package/dist/design-data.js +459 -30
  24. package/dist/design-data.js.map +1 -1
  25. package/dist/design-mode.d.ts +3 -2
  26. package/dist/design-mode.d.ts.map +1 -1
  27. package/dist/design-react-core.d.ts +5 -15
  28. package/dist/design-react-core.d.ts.map +1 -1
  29. package/dist/design-react-core.js +2 -2
  30. package/dist/design-react.d.ts +2 -2
  31. package/dist/design.d.ts +2 -2
  32. package/dist/events.d.ts +32 -6
  33. package/dist/events.d.ts.map +1 -1
  34. package/dist/i18n-client.d.ts.map +1 -1
  35. package/dist/i18n-client.js.map +1 -1
  36. package/dist/i18n.d.ts +1 -2
  37. package/dist/i18n.d.ts.map +1 -1
  38. package/dist/modeDetection.js +0 -18
  39. package/dist/modeDetection.js.map +1 -1
  40. package/dist/scapi.d.ts +2185 -466
  41. package/dist/scapi.d.ts.map +1 -1
  42. package/dist/scapi.js +1 -1
  43. package/dist/scapi.js.map +1 -1
  44. package/dist/schema.d.ts +17 -15
  45. package/dist/schema.d.ts.map +1 -1
  46. package/dist/security-react.d.ts +34 -0
  47. package/dist/security-react.d.ts.map +1 -0
  48. package/dist/security-react.js +21 -0
  49. package/dist/security-react.js.map +1 -0
  50. package/dist/security.d.ts +61 -0
  51. package/dist/security.d.ts.map +1 -0
  52. package/dist/security.js +304 -0
  53. package/dist/security.js.map +1 -0
  54. package/dist/site-context.d.ts +43 -27
  55. package/dist/site-context.d.ts.map +1 -1
  56. package/dist/site-context.js +2 -2
  57. package/dist/site-context2.js +41 -31
  58. package/dist/site-context2.js.map +1 -1
  59. package/dist/types.d.ts +19 -3
  60. package/dist/types.d.ts.map +1 -1
  61. package/dist/types2.d.ts +89 -63
  62. package/dist/types2.d.ts.map +1 -1
  63. package/dist/types3.d.ts +1 -35
  64. package/dist/types3.d.ts.map +1 -1
  65. package/package.json +15 -20
  66. package/dist/DesignFrame.js +0 -204
  67. package/dist/DesignFrame.js.map +0 -1
  68. package/dist/custom-global-preferences.d.ts +0 -20
  69. package/dist/custom-global-preferences.d.ts.map +0 -1
  70. package/dist/custom-global-preferences.js +0 -31
  71. package/dist/custom-global-preferences.js.map +0 -1
  72. package/dist/custom-site-preferences.d.ts +0 -20
  73. package/dist/custom-site-preferences.d.ts.map +0 -1
  74. package/dist/custom-site-preferences.js +0 -31
  75. package/dist/custom-site-preferences.js.map +0 -1
  76. package/dist/data-store-custom-global-preferences.d.ts +0 -2
  77. package/dist/data-store-custom-global-preferences.js +0 -6
  78. package/dist/data-store-custom-site-preferences.d.ts +0 -2
  79. package/dist/data-store-custom-site-preferences.js +0 -6
  80. package/dist/data-store-gcp-preferences.d.ts +0 -2
  81. package/dist/data-store-gcp-preferences.js +0 -6
  82. package/dist/gcp-preferences.d.ts +0 -52
  83. package/dist/gcp-preferences.d.ts.map +0 -1
  84. package/dist/gcp-preferences.js +0 -64
  85. package/dist/gcp-preferences.js.map +0 -1
  86. package/dist/utils.js +0 -90
  87. package/dist/utils.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"data-store.d.ts","names":[],"sources":["../src/data-store/utils.ts","../src/data-store/middleware/login-preferences.ts","../src/data-store/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAkCc,KATF,mBASE,CAAA,CAAA,CAAA,GATuB,UASvB,CAAA,OATyC,aASzC,CATuD,CASvD,GAAA,IAAA,CAAA,CAAA;AACmB,KARrB,iBAAA,GAQqB,MAAA,GAAA,CAAA,CAAA,OAAA,EARmB,QAQnB,CAR4B,qBAQ5B,CAAA,EAAA,GAAA,MAAA,CAAA;AAApB,KAND,cAMC,CAAA,SAAA,OAAA,CAAA,GAAA;EACW,KAAA,CAAA,EANZ,MAMY;CAA4B;AAEhC,KALR,0BAKQ,CAAA,CAAA,CAAA,GAAA;EAAwB,QAAA,EAJ9B,iBAI8B;EAAT,OAAA,EAHtB,mBAGsB,CAHF,CAGE,CAAA;EAAoC,SAAA,CAAA,EAAA,CAAA,KAAA,EAF/C,MAE+C,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAFnB,CAEmB;EAAC,aAAA,CAAA,EAAA,OAAA,GAAA,UAAA;EAUxD,aAAA,CAAA,EAVI,CAUJ,GAAA,CAAA,CAAA,OAAsB,EAVH,QAU8B,CAVrB,qBAUC,CAAmB,EAAA,GAVO,CAUP,CAAA;AAgBhE,CAAA;;;;;;AAwDA;;AAAgF,iBAxEhE,sBAwEgE,CAAA,CAAA,CAAA,CAAA,CAAA,EAxEnC,mBAwEmC,CAxEf,CAwEe,CAAA;;;;;;ACrGhF;AAIA;AASA;;;;;iBDgCgB,sCAAsC,2BAA2B,KAAK,mBAAmB;;;AETzG;;;;;;iBFiEsB,kDAAkD,QAAQ,eAAe;;;AAtFjF,KCfF,gBAAA,GDeE;EACmB,wBAAA,CAAA,EAAA,OAAA;CAApB;AACW,cCbX,uBDaW,ECbY,cAAA,CAAA,aDaZ,CCbY,gBDaZ,GAAA,IAAA,CAAA;;;;;;;AAYR,iBChBA,mBAAA,CDgBiD,OAApB,EChBA,QDgBA,CChBS,qBDgBU,CAAA,CAAA,EChBe,gBDgBf;;;AAgBsB,cETzE,mBFSyE,EETtD,cAAA,CAAA,kBFSsD,CETtD,QFSsD,CAAA,EAAA"}
1
+ {"version":3,"file":"data-store.d.ts","names":[],"sources":["../src/data-store/utils.ts","../src/data-store/logger-context.ts","../src/data-store/middleware/custom-site-preferences.ts","../src/data-store/middleware/custom-global-preferences.ts","../src/data-store/middleware/gcp-preferences.ts","../src/data-store/middleware/login-preferences.ts","../src/data-store/index.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1,14 +1,403 @@
1
- import "./site-context2.js";
1
+ import { i as siteContext } from "./site-context2.js";
2
2
  import "./apply-url-config.js";
3
- import { i as prefixWithSiteId, n as createDataStoreMiddleware, r as getDataStoreEntry, t as createDataStoreContext } from "./utils.js";
4
- import { i as sitePreferencesContext, n as customSitePreferencesMiddleware, r as getSitePreferences, t as DEFAULT_SITE_PREFERENCES_KEY } from "./custom-site-preferences.js";
5
- import { i as getCustomGlobalPreferences, n as customGlobalPreferencesContext, r as customGlobalPreferencesMiddleware, t as DEFAULT_CUSTOM_GLOBAL_PREFERENCES_KEY } from "./custom-global-preferences.js";
6
- import { a as getGcpPreferences, i as getGcpApiKey, n as gcpPreferencesContext, r as gcpPreferencesMiddleware, t as DEFAULT_GCP_PREFERENCES_KEY } from "./gcp-preferences.js";
7
- import { DataStore, DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError } from "@salesforce/mrt-utilities/data-store";
3
+ import { createContext } from "react-router";
4
+ import { DataStore, DataStore as DataStore$1, DataStoreNotFoundError, DataStoreNotFoundError as DataStoreNotFoundError$1, DataStoreServiceError, DataStoreServiceError as DataStoreServiceError$1, DataStoreUnavailableError, DataStoreUnavailableError as DataStoreUnavailableError$1 } from "@salesforce/mrt-utilities/data-store";
8
5
 
6
+ //#region src/data-store/logger-context.ts
7
+ function formatMessage(message, metadata) {
8
+ if (!metadata) return message;
9
+ try {
10
+ return `${message} ${JSON.stringify(metadata, replacerForErrors)}`;
11
+ } catch {
12
+ return `${message} [unserializable metadata]`;
13
+ }
14
+ }
15
+ function replacerForErrors(_key, value) {
16
+ if (value instanceof Error) return {
17
+ name: value.name,
18
+ message: value.message,
19
+ ...value.stack && { stack: value.stack }
20
+ };
21
+ return value;
22
+ }
23
+ /**
24
+ * Default logger used when nothing has been injected via
25
+ * {@link dataStoreLoggerContext}. Routes warnings to `console.warn` and
26
+ * errors to `console.error` so diagnostics remain visible in environments
27
+ * (tests, scripts, hosts that haven't wired a structured logger) where the
28
+ * SDK is invoked outside the storefront template. `info` and `debug` are
29
+ * no-ops to avoid noisy default output.
30
+ */
31
+ const consoleLogger = Object.freeze({
32
+ error(message, metadata) {
33
+ console.error(formatMessage(message, metadata));
34
+ },
35
+ warn(message, metadata) {
36
+ console.warn(formatMessage(message, metadata));
37
+ },
38
+ info() {},
39
+ debug() {}
40
+ });
41
+ /**
42
+ * Router context the SDK reads to obtain a request-scoped structured logger.
43
+ *
44
+ * Hosts (e.g. the storefront template) populate this from their own logging
45
+ * middleware. When unset, {@link getDataStoreLogger} falls back to a
46
+ * console-based logger so warnings remain visible.
47
+ *
48
+ * Defaults to `null` (not `undefined`) because React Router's
49
+ * `context.get()` throws when `defaultValue === undefined`.
50
+ */
51
+ const dataStoreLoggerContext = createContext(null);
52
+ /**
53
+ * Read the data-store logger from router context, falling back to a
54
+ * console-based default when nothing has been injected.
55
+ *
56
+ * Use this from inside SDK middleware/loaders that have access to a
57
+ * {@link RouterContextProvider}.
58
+ */
59
+ function getDataStoreLogger(context) {
60
+ return context.get(dataStoreLoggerContext) ?? consoleLogger;
61
+ }
62
+
63
+ //#endregion
64
+ //#region src/data-store/utils.ts
65
+ /**
66
+ * Creates a typed React Router context for data store entries.
67
+ *
68
+ * Initializes the context with `null` so middleware can populate it during requests.
69
+ *
70
+ * @returns React Router context key for data store values
71
+ */
72
+ function createDataStoreContext() {
73
+ return createContext(null);
74
+ }
75
+ /**
76
+ * Creates a React Router middleware that fetches a single MRT data store entry on every
77
+ * request and stores the resulting value in the supplied router context.
78
+ *
79
+ * Failure handling is controlled by `options.onUnavailable`:
80
+ * - `'throw'` (default for the factory): rethrow `DataStoreUnavailableError` and
81
+ * `DataStoreServiceError` with a stable error message. Fail-fast — the request errors out.
82
+ * - `'fallback'`: log a warning and resolve to `options.fallbackValue` when configured, or
83
+ * to the missing state (context not populated) when no `fallbackValue` is provided. The
84
+ * request continues without crashing the middleware chain.
85
+ *
86
+ * `DataStoreNotFoundError` is always treated as "missing" (warn, do not populate context),
87
+ * regardless of `onUnavailable` — a not-found entry is an expected steady-state for
88
+ * features that haven't been published yet, not a service failure.
89
+ *
90
+ * Errors thrown from `options.transform` propagate to the caller — they indicate a
91
+ * programmer error in the middleware definition, not data-store unavailability.
92
+ *
93
+ * @param options - See {@link DataStoreMiddlewareOptions}.
94
+ * @returns React Router middleware for server requests.
95
+ *
96
+ * @env AWS_REGION (required): AWS region for the data store table (e.g., `us-east-1`).
97
+ * @env MOBIFY_PROPERTY_ID (required): MRT property identifier.
98
+ * @env DEPLOY_TARGET (required): MRT deploy target (e.g., `production`).
99
+ */
100
+ function createDataStoreMiddleware(options) {
101
+ const { entryKey, context: contextKey, onUnavailable = "throw", fallbackValue } = options;
102
+ const transform = options.transform ?? ((value) => value);
103
+ const dataStoreMiddleware$1 = async ({ context }, next) => {
104
+ const result = await loadDataStoreEntry({
105
+ entryKey: typeof entryKey === "function" ? entryKey(context) : entryKey,
106
+ context,
107
+ transform,
108
+ onUnavailable,
109
+ fallbackValue
110
+ });
111
+ if (result.state === "value" || result.state === "fallback") context.set(contextKey, result.value);
112
+ return next();
113
+ };
114
+ return dataStoreMiddleware$1;
115
+ }
116
+ /**
117
+ * Lazy variant of {@link createDataStoreMiddleware}. Instead of fetching the
118
+ * entry up-front during middleware execution, this stores a memoized loader
119
+ * in the router context. Consumers call {@link readLazyDataStoreEntry} to
120
+ * trigger the fetch on demand — pages that never read the value never pay
121
+ * for the data-store call.
122
+ *
123
+ * Repeated reads within the same request share the in-flight promise so
124
+ * the entry is fetched at most once per request.
125
+ *
126
+ * Failure handling matches the eager variant: `onUnavailable` and
127
+ * `fallbackValue` are honored when the underlying fetch fails. The fallback
128
+ * value (or `null` for the missing state) surfaces through
129
+ * {@link readLazyDataStoreEntry}.
130
+ *
131
+ * Use this for entries that only a subset of routes consume (e.g. config
132
+ * read by a single feature) rather than entries needed on every request.
133
+ */
134
+ function createLazyDataStoreMiddleware(options) {
135
+ const { entryKey, context: contextKey, onUnavailable = "throw", fallbackValue } = options;
136
+ const transform = options.transform ?? ((value) => value);
137
+ const lazyMiddleware = async ({ context }, next) => {
138
+ let pending;
139
+ const loader = () => {
140
+ if (!pending) pending = loadDataStoreEntry({
141
+ entryKey: typeof entryKey === "function" ? entryKey(context) : entryKey,
142
+ context,
143
+ transform,
144
+ onUnavailable,
145
+ fallbackValue
146
+ }).then((result) => result.state === "missing" ? null : result.value);
147
+ return pending;
148
+ };
149
+ context.set(contextKey, loader);
150
+ return next();
151
+ };
152
+ return lazyMiddleware;
153
+ }
154
+ /**
155
+ * Reads a value populated by {@link createLazyDataStoreMiddleware}. Triggers
156
+ * the underlying data-store fetch on first call and reuses the cached
157
+ * promise on subsequent calls within the same request.
158
+ *
159
+ * Returns `null` when the lazy middleware did not run (no loader in
160
+ * context) or when the entry is missing/invalid.
161
+ */
162
+ async function readLazyDataStoreEntry(context, contextKey) {
163
+ const loader = context.get(contextKey);
164
+ if (typeof loader !== "function") return null;
165
+ return loader();
166
+ }
167
+ /**
168
+ * Internal helper shared by the eager and lazy middleware factories.
169
+ * Performs the fetch + transform pipeline and resolves all three error
170
+ * paths (unavailable / not-found / service-error) consistently. Returns a
171
+ * tagged result so callers can decide whether to populate the context
172
+ * synchronously (eager middleware) or hand the value back to a lazy reader.
173
+ */
174
+ async function loadDataStoreEntry(args) {
175
+ const { entryKey, context, transform, onUnavailable, fallbackValue } = args;
176
+ const logger = getDataStoreLogger(context);
177
+ try {
178
+ const entry = await getDataStoreEntry(entryKey);
179
+ if (!entry?.value || typeof entry.value !== "object") {
180
+ logger.warn(`Data store entry '${entryKey}' not found or invalid.`, { entryKey });
181
+ return { state: "missing" };
182
+ }
183
+ return {
184
+ state: "value",
185
+ value: transform(entry.value)
186
+ };
187
+ } catch (error) {
188
+ if (error instanceof DataStoreNotFoundError$1) {
189
+ logger.warn(`Data store entry '${entryKey}' not found.`, {
190
+ entryKey,
191
+ error
192
+ });
193
+ return { state: "missing" };
194
+ }
195
+ if (error instanceof DataStoreUnavailableError$1 || error instanceof DataStoreServiceError$1) return resolveDataStoreFallback({
196
+ entryKey,
197
+ context,
198
+ error,
199
+ onUnavailable,
200
+ fallbackValue,
201
+ logger
202
+ });
203
+ throw error;
204
+ }
205
+ }
206
+ function resolveDataStoreFallback(args) {
207
+ const { entryKey, context, error, onUnavailable, fallbackValue, logger } = args;
208
+ const reason = error instanceof DataStoreServiceError$1 ? "service error" : "unavailable";
209
+ if (onUnavailable === "fallback") {
210
+ if (typeof fallbackValue !== "undefined") {
211
+ const resolved = typeof fallbackValue === "function" ? fallbackValue(context) : fallbackValue;
212
+ logger.warn(`Data store ${reason} for '${entryKey}'. Using configured fallback value.`, {
213
+ entryKey,
214
+ reason,
215
+ error
216
+ });
217
+ return {
218
+ state: "fallback",
219
+ value: resolved
220
+ };
221
+ }
222
+ logger.warn(`Data store ${reason} for '${entryKey}'. No fallback configured; treating entry as missing.`, {
223
+ entryKey,
224
+ reason,
225
+ error
226
+ });
227
+ return { state: "missing" };
228
+ }
229
+ if (error instanceof DataStoreUnavailableError$1) throw new Error("Data store is unavailable. Ensure AWS_REGION, MOBIFY_PROPERTY_ID, and DEPLOY_TARGET are set.");
230
+ throw new Error(`Data store request failed for '${entryKey}'.`);
231
+ }
232
+ /**
233
+ * Read a data-store entry through the singleton MRT utilities API.
234
+ * The underlying implementation (production DynamoDB vs development pseudo store)
235
+ * is resolved by `@salesforce/mrt-utilities/data-store` export conditions.
236
+ *
237
+ * @param key - Data-store entry key
238
+ * @returns Data-store entry or null when missing/invalid shape
239
+ */
240
+ async function getDataStoreEntry(key) {
241
+ const entry = await DataStore$1.getDataStore().getEntry(key);
242
+ if (!entry || typeof entry !== "object") return null;
243
+ return entry;
244
+ }
245
+ /**
246
+ * Creates an entryKey function that prefixes the given suffix with the current site ID.
247
+ *
248
+ * @param suffix - The entry key suffix (e.g., "custom-site-preferences")
249
+ * @returns A function compatible with `DataStoreMiddlewareOptions.entryKey`
250
+ */
251
+ function prefixWithSiteId(suffix) {
252
+ return (context) => {
253
+ const siteId = context.get(siteContext)?.site?.id;
254
+ if (!siteId) throw new Error("Site id not found. Ensure site context middleware runs before data-store middleware.");
255
+ return `${siteId}-${suffix}`;
256
+ };
257
+ }
258
+
259
+ //#endregion
260
+ //#region src/data-store/middleware/custom-site-preferences.ts
261
+ const sitePreferencesContext = createDataStoreContext();
262
+ /**
263
+ * Read site preferences from router context.
264
+ *
265
+ * @param context - Router context provider
266
+ * @returns Site preferences data stored by data-store middleware
267
+ */
268
+ function getSitePreferences(context) {
269
+ const data = context.get(sitePreferencesContext);
270
+ if (!data) {
271
+ getDataStoreLogger(context).warn("Data store context not found. Ensure data-store middleware runs before loaders and the required env vars are set.");
272
+ return {};
273
+ }
274
+ return data;
275
+ }
276
+ /**
277
+ * Middleware that reads the site-scoped `custom-site-preferences` entry from the MRT data
278
+ * store and stores it in {@link sitePreferencesContext}. The entry key is prefixed with
279
+ * the current site id (e.g. `acme-custom-site-preferences`).
280
+ *
281
+ * Defaults to graceful degradation: if the data store is unavailable or returns a service
282
+ * error, the request continues with `{}` as the preferences value rather than crashing.
283
+ * Set `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back into
284
+ * fail-fast behavior. The env var is read once at module load.
285
+ *
286
+ * Must run after the site-context middleware (so the site id is available for the entry
287
+ * key) and before any loader that calls {@link getSitePreferences}.
288
+ */
289
+ const customSitePreferencesMiddleware = createDataStoreMiddleware({
290
+ entryKey: prefixWithSiteId("custom-site-preferences"),
291
+ context: sitePreferencesContext,
292
+ onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === "throw" ? "throw" : "fallback",
293
+ fallbackValue: {}
294
+ });
295
+
296
+ //#endregion
297
+ //#region src/data-store/middleware/custom-global-preferences.ts
298
+ const DEFAULT_CUSTOM_GLOBAL_PREFERENCES_KEY = "custom-global-preferences";
299
+ const customGlobalPreferencesContext = createDataStoreContext();
300
+ /**
301
+ * Read custom global preferences from router context.
302
+ *
303
+ * @param context - Router context provider
304
+ * @returns Custom global preferences data stored by data-store middleware
305
+ */
306
+ function getCustomGlobalPreferences(context) {
307
+ const data = context.get(customGlobalPreferencesContext);
308
+ if (!data) {
309
+ getDataStoreLogger(context).warn("Custom global preferences context not found. Ensure data-store middleware runs before loaders and the required env vars are set.");
310
+ return {};
311
+ }
312
+ return data;
313
+ }
314
+ /**
315
+ * Middleware that reads the global `custom-global-preferences` entry from the MRT data
316
+ * store and stores it in {@link customGlobalPreferencesContext}.
317
+ *
318
+ * Defaults to graceful degradation: if the data store is unavailable or returns a service
319
+ * error, the request continues with `{}` as the preferences value rather than crashing.
320
+ * Set `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back into
321
+ * fail-fast behavior. The env var is read once at module load.
322
+ */
323
+ const customGlobalPreferencesMiddleware = createDataStoreMiddleware({
324
+ entryKey: DEFAULT_CUSTOM_GLOBAL_PREFERENCES_KEY,
325
+ context: customGlobalPreferencesContext,
326
+ onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === "throw" ? "throw" : "fallback",
327
+ fallbackValue: {}
328
+ });
329
+
330
+ //#endregion
331
+ //#region src/data-store/middleware/gcp-preferences.ts
332
+ const DEFAULT_GCP_PREFERENCES_KEY = "gcp";
333
+ /**
334
+ * Map keys inside the `gcp` data store entry. The ECOM MRT sync job writes
335
+ * to these exact keys; keep in sync with the sync job contract.
336
+ */
337
+ const API_KEY_MAP_KEY = "api-key";
338
+ const gcpPreferencesContext = createDataStoreContext();
339
+ /**
340
+ * Read the GCP (Google Cloud Platform) preferences object from router context.
341
+ *
342
+ * The preferences are sourced from the MRT data store entry `gcp`, which is
343
+ * populated only for storefronts connecting to production ECOM instances.
344
+ * In non-production environments, or when the entry is missing, returns an
345
+ * object whose fields are all empty/default.
346
+ *
347
+ * @param context - Router context provider
348
+ * @returns GCP preferences object; fields are empty/default when the entry is unavailable
349
+ */
350
+ function getGcpPreferences(context) {
351
+ const data = context.get(gcpPreferencesContext);
352
+ if (data === null) {
353
+ getDataStoreLogger(context).warn("GCP preferences context not found. Ensure gcpPreferencesMiddleware runs before loaders, or expect empty values in environments without the MRT data store entry.");
354
+ return { apiKey: "" };
355
+ }
356
+ return data;
357
+ }
358
+ /**
359
+ * Convenience getter for the Google Cloud API key alone.
360
+ *
361
+ * Equivalent to `getGcpPreferences(context).apiKey`.
362
+ *
363
+ * @param context - Router context provider
364
+ * @returns The GCP API key, or an empty string when unavailable
365
+ */
366
+ function getGcpApiKey(context) {
367
+ return getGcpPreferences(context).apiKey;
368
+ }
369
+ /**
370
+ * Middleware that reads the OOTB GCP preferences from the MRT data store and
371
+ * stores them in the router context. The entry shape is `{ "api-key": string, ... }`
372
+ * under data store key `gcp`. Missing/invalid fields coerce to empty/default values.
373
+ *
374
+ * Only available for storefronts connecting to production ECOM instances. When the entry
375
+ * is not synced (e.g. the GCP feature flag is off in ECOM), the underlying fetch surfaces
376
+ * as `DataStoreNotFoundError` and the context is left unset; consumers see the empty
377
+ * default `{ apiKey: '' }` via {@link getGcpPreferences}.
378
+ *
379
+ * Defaults to graceful degradation: if the data store is unavailable or returns a service
380
+ * error, the request continues with `{ apiKey: '' }` rather than crashing. Set
381
+ * `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back into
382
+ * fail-fast behavior. The env var is read once at module load.
383
+ *
384
+ * Must run before any loader/middleware that reads `getGcpPreferences(context)` or
385
+ * `getGcpApiKey(context)`.
386
+ */
387
+ const gcpPreferencesMiddleware = createDataStoreMiddleware({
388
+ entryKey: DEFAULT_GCP_PREFERENCES_KEY,
389
+ context: gcpPreferencesContext,
390
+ onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === "throw" ? "throw" : "fallback",
391
+ fallbackValue: { apiKey: "" },
392
+ transform: (value) => {
393
+ const rawKey = value[API_KEY_MAP_KEY];
394
+ return { apiKey: typeof rawKey === "string" ? rawKey : "" };
395
+ }
396
+ });
397
+
398
+ //#endregion
9
399
  //#region src/data-store/middleware/login-preferences.ts
10
400
  const loginPreferencesContext = createDataStoreContext();
11
- const DATA_STORE_UNAVAILABLE_MODE = process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE;
12
401
  /**
13
402
  * Read login preferences from router context.
14
403
  *
@@ -18,15 +407,28 @@ const DATA_STORE_UNAVAILABLE_MODE = process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MO
18
407
  function getLoginPreferences(context) {
19
408
  const data = context.get(loginPreferencesContext);
20
409
  if (!data) {
21
- console.warn("Login preferences context not found. Ensure data-store middleware runs before loaders and the required env vars are set.");
410
+ getDataStoreLogger(context).warn("Login preferences context not found. Ensure data-store middleware runs before loaders and the required env vars are set.");
22
411
  return {};
23
412
  }
24
413
  return data;
25
414
  }
415
+ /**
416
+ * Middleware that reads the site-scoped `login-preferences` entry from the MRT data store
417
+ * and stores its `data` field in {@link loginPreferencesContext}. The entry key is
418
+ * prefixed with the current site id (e.g. `acme-login-preferences`).
419
+ *
420
+ * Defaults to graceful degradation: if the data store is unavailable or returns a service
421
+ * error, the request continues with `{ emailVerificationEnabled: false }` rather than
422
+ * crashing. Set `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back
423
+ * into fail-fast behavior. The env var is read once at module load.
424
+ *
425
+ * Must run after the site-context middleware (so the site id is available for the entry
426
+ * key) and before any loader that calls {@link getLoginPreferences}.
427
+ */
26
428
  const loginPreferencesMiddleware = createDataStoreMiddleware({
27
429
  entryKey: prefixWithSiteId("login-preferences"),
28
430
  context: loginPreferencesContext,
29
- onUnavailable: DATA_STORE_UNAVAILABLE_MODE === "fallback" ? "fallback" : "throw",
431
+ onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === "throw" ? "throw" : "fallback",
30
432
  fallbackValue: { emailVerificationEnabled: false },
31
433
  transform: (value) => value.data
32
434
  });
@@ -41,5 +443,5 @@ const dataStoreMiddleware = [
41
443
  ];
42
444
 
43
445
  //#endregion
44
- export { DEFAULT_CUSTOM_GLOBAL_PREFERENCES_KEY, DEFAULT_GCP_PREFERENCES_KEY, DEFAULT_SITE_PREFERENCES_KEY, DataStore, DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError, createDataStoreContext, createDataStoreMiddleware, customGlobalPreferencesContext, dataStoreMiddleware, gcpPreferencesContext, getCustomGlobalPreferences, getDataStoreEntry, getGcpApiKey, getGcpPreferences, getLoginPreferences, getSitePreferences, loginPreferencesContext, sitePreferencesContext };
446
+ export { DataStore, DataStoreNotFoundError, DataStoreServiceError, DataStoreUnavailableError, createDataStoreContext, createDataStoreMiddleware, createLazyDataStoreMiddleware, dataStoreLoggerContext, dataStoreMiddleware, getCustomGlobalPreferences, getDataStoreEntry, getDataStoreLogger, getGcpApiKey, getGcpPreferences, getLoginPreferences, getSitePreferences, readLazyDataStoreEntry };
45
447
  //# sourceMappingURL=data-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-store.js","names":[],"sources":["../src/data-store/middleware/login-preferences.ts","../src/data-store/index.ts"],"sourcesContent":["/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { RouterContextProvider } from 'react-router';\nimport { createDataStoreContext, createDataStoreMiddleware, prefixWithSiteId } from '../utils';\n\nexport type LoginPreferences = {\n emailVerificationEnabled?: boolean;\n};\n\nexport const loginPreferencesContext = createDataStoreContext<LoginPreferences>();\nconst DATA_STORE_UNAVAILABLE_MODE = process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE;\n\n/**\n * Read login preferences from router context.\n *\n * @param context - Router context provider\n * @returns Login preferences data stored by data-store middleware\n */\nexport function getLoginPreferences(context: Readonly<RouterContextProvider>): LoginPreferences {\n const data = context.get(loginPreferencesContext);\n if (!data) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Login preferences context not found. Ensure data-store middleware runs before loaders and the required env vars are set.'\n );\n return {};\n }\n return data;\n}\n\nexport const loginPreferencesMiddleware = createDataStoreMiddleware<LoginPreferences>({\n entryKey: prefixWithSiteId('login-preferences'),\n context: loginPreferencesContext,\n onUnavailable: DATA_STORE_UNAVAILABLE_MODE === 'fallback' ? 'fallback' : 'throw',\n fallbackValue: { emailVerificationEnabled: false },\n transform: (value) => value.data as LoginPreferences,\n});\n","/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport { createDataStoreMiddleware } from './utils';\nexport { createDataStoreContext } from './utils';\nexport { getDataStoreEntry } from './utils';\nexport {\n DEFAULT_SITE_PREFERENCES_KEY,\n getSitePreferences,\n sitePreferencesContext,\n} from './middleware/custom-site-preferences';\nexport {\n customGlobalPreferencesContext,\n DEFAULT_CUSTOM_GLOBAL_PREFERENCES_KEY,\n getCustomGlobalPreferences,\n} from './middleware/custom-global-preferences';\nexport {\n DEFAULT_GCP_PREFERENCES_KEY,\n gcpPreferencesContext,\n getGcpApiKey,\n getGcpPreferences,\n} from './middleware/gcp-preferences';\nexport type { DataStoreMiddlewareOptions } from './utils';\nexport type { SitePreferences } from './middleware/custom-site-preferences';\nexport type { DataStoreContextKey, DataStoreEntryKey } from './utils';\nexport type { DataStoreEntry } from './utils';\nexport type { CustomGlobalPreferences } from './middleware/custom-global-preferences';\nexport { getLoginPreferences, loginPreferencesContext } from './middleware/login-preferences';\nexport type { LoginPreferences } from './middleware/login-preferences';\nexport type { GcpPreferences } from './middleware/gcp-preferences';\nexport { DataStore } from '@salesforce/mrt-utilities/data-store';\nexport {\n DataStoreNotFoundError,\n DataStoreServiceError,\n DataStoreUnavailableError,\n} from '@salesforce/mrt-utilities/data-store';\n\nimport { customSitePreferencesMiddleware } from './middleware/custom-site-preferences';\nimport { customGlobalPreferencesMiddleware } from './middleware/custom-global-preferences';\nimport { gcpPreferencesMiddleware } from './middleware/gcp-preferences';\nimport { loginPreferencesMiddleware } from './middleware/login-preferences';\n\nexport const dataStoreMiddleware = [\n customSitePreferencesMiddleware,\n customGlobalPreferencesMiddleware,\n gcpPreferencesMiddleware,\n loginPreferencesMiddleware,\n];\n"],"mappings":";;;;;;;;;AAuBA,MAAa,0BAA0B,wBAA0C;AACjF,MAAM,8BAA8B,QAAQ,IAAI;;;;;;;AAQhD,SAAgB,oBAAoB,SAA4D;CAC5F,MAAM,OAAO,QAAQ,IAAI,wBAAwB;AACjD,KAAI,CAAC,MAAM;AAEP,UAAQ,KACJ,2HACH;AACD,SAAO,EAAE;;AAEb,QAAO;;AAGX,MAAa,6BAA6B,0BAA4C;CAClF,UAAU,iBAAiB,oBAAoB;CAC/C,SAAS;CACT,eAAe,gCAAgC,aAAa,aAAa;CACzE,eAAe,EAAE,0BAA0B,OAAO;CAClD,YAAY,UAAU,MAAM;CAC/B,CAAC;;;;ACKF,MAAa,sBAAsB;CAC/B;CACA;CACA;CACA;CACH"}
1
+ {"version":3,"file":"data-store.js","names":["consoleLogger: DataStoreLogger","dataStoreMiddleware: MiddlewareFunction<Response>","dataStoreMiddleware","lazyMiddleware: MiddlewareFunction<Response>","pending: Promise<T | null> | undefined","loader: LazyDataStoreLoader<T>","DataStoreNotFoundError","DataStoreUnavailableError","DataStoreServiceError","DataStore"],"sources":["../src/data-store/logger-context.ts","../src/data-store/utils.ts","../src/data-store/middleware/custom-site-preferences.ts","../src/data-store/middleware/custom-global-preferences.ts","../src/data-store/middleware/gcp-preferences.ts","../src/data-store/middleware/login-preferences.ts","../src/data-store/index.ts"],"sourcesContent":["/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// TODO: Remove this file once the SDK-level `loggerContext` lifted from the storefront\n// template lands. This data-store-scoped logger seam exists only because the SDK can't\n// import the template's `loggerContext` (inverted dep). Once the logger is platform-level\n// infra in the SDK, the data-store middleware should read that context directly and this\n// file can be deleted.\n\nimport { createContext, type RouterContextProvider } from 'react-router';\n\n/**\n * Minimal structured-logger interface the data-store middleware depends on.\n *\n * Matches the shape of the host application's `Logger` (see the storefront\n * template's `src/lib/logger.ts`) so a host can pass through its own logger\n * object via {@link dataStoreLoggerContext} without an adapter.\n *\n * The data-store middleware emits at `warn` level today; the full interface\n * is exposed so future SDK middlewares that need richer levels stay\n * consistent with this contract.\n */\nexport interface DataStoreLogger {\n error(message: string, metadata?: Record<string, unknown>): void;\n warn(message: string, metadata?: Record<string, unknown>): void;\n info(message: string, metadata?: Record<string, unknown>): void;\n debug(message: string, metadata?: Record<string, unknown>): void;\n}\n\nfunction formatMessage(message: string, metadata?: Record<string, unknown>): string {\n if (!metadata) return message;\n try {\n return `${message} ${JSON.stringify(metadata, replacerForErrors)}`;\n } catch {\n // Metadata may contain cycles, BigInt, or other unserializable values. The default\n // logger must never throw — that would defeat the data-store middleware's fail-soft\n // contract. Drop the metadata payload rather than crashing the request.\n return `${message} [unserializable metadata]`;\n }\n}\n\nfunction replacerForErrors(_key: string, value: unknown): unknown {\n if (value instanceof Error) {\n return { name: value.name, message: value.message, ...(value.stack && { stack: value.stack }) };\n }\n return value;\n}\n\n/**\n * Default logger used when nothing has been injected via\n * {@link dataStoreLoggerContext}. Routes warnings to `console.warn` and\n * errors to `console.error` so diagnostics remain visible in environments\n * (tests, scripts, hosts that haven't wired a structured logger) where the\n * SDK is invoked outside the storefront template. `info` and `debug` are\n * no-ops to avoid noisy default output.\n */\nconst consoleLogger: DataStoreLogger = Object.freeze({\n error(message: string, metadata?: Record<string, unknown>): void {\n // eslint-disable-next-line no-console\n console.error(formatMessage(message, metadata));\n },\n warn(message: string, metadata?: Record<string, unknown>): void {\n // eslint-disable-next-line no-console\n console.warn(formatMessage(message, metadata));\n },\n info(): void {\n // intentional no-op: keeps the default logger quiet outside warn/error\n },\n debug(): void {\n // intentional no-op: keeps the default logger quiet outside warn/error\n },\n});\n\n/**\n * Router context the SDK reads to obtain a request-scoped structured logger.\n *\n * Hosts (e.g. the storefront template) populate this from their own logging\n * middleware. When unset, {@link getDataStoreLogger} falls back to a\n * console-based logger so warnings remain visible.\n *\n * Defaults to `null` (not `undefined`) because React Router's\n * `context.get()` throws when `defaultValue === undefined`.\n */\nexport const dataStoreLoggerContext = createContext<DataStoreLogger | null>(null);\n\n/**\n * Read the data-store logger from router context, falling back to a\n * console-based default when nothing has been injected.\n *\n * Use this from inside SDK middleware/loaders that have access to a\n * {@link RouterContextProvider}.\n */\nexport function getDataStoreLogger(context: Readonly<RouterContextProvider>): DataStoreLogger {\n return context.get(dataStoreLoggerContext) ?? consoleLogger;\n}\n","/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { type MiddlewareFunction, type RouterContextProvider, createContext } from 'react-router';\nimport {\n DataStore,\n DataStoreNotFoundError,\n DataStoreServiceError,\n DataStoreUnavailableError,\n} from '@salesforce/mrt-utilities/data-store';\nimport { siteContext } from '../site-context';\nimport { type DataStoreLogger, getDataStoreLogger } from './logger-context';\n\nexport type DataStoreContextKey<T> = ReturnType<typeof createContext<T | null>>;\n\nexport type DataStoreEntryKey = string | ((context: Readonly<RouterContextProvider>) => string);\n\nexport type DataStoreEntry<TValue = unknown> = {\n value?: TValue;\n};\n\n/**\n * Options for {@link createDataStoreMiddleware} and {@link createLazyDataStoreMiddleware}.\n *\n * @typeParam T - The shape stored in `context` after the entry is fetched and transformed.\n */\nexport type DataStoreMiddlewareOptions<T> = {\n /**\n * The data store entry key, or a function that derives it from request context (used\n * for site-scoped keys — see {@link prefixWithSiteId}).\n */\n entryKey: DataStoreEntryKey;\n /**\n * The React Router context the resolved value is written to. Create one with\n * {@link createDataStoreContext}.\n */\n context: DataStoreContextKey<T>;\n /**\n * Optional projection from the raw entry value to the typed shape stored in context.\n * Defaults to the identity function (the raw value cast to `T`). Throws from this\n * function propagate to the caller; do not use it as a place to handle data-store\n * errors.\n */\n transform?: (value: Record<string, unknown>) => T;\n /**\n * How the middleware reacts when the data store cannot serve the entry\n * (`DataStoreUnavailableError` or `DataStoreServiceError`). `DataStoreNotFoundError`\n * is always handled gracefully and ignores this setting.\n *\n * - `'throw'` *(factory default)*: rethrow with a stable error message. Use when the\n * entry is required and a failure should surface as a 5xx.\n * - `'fallback'`: warn and resolve to {@link DataStoreMiddlewareOptions.fallbackValue}\n * (or the missing state if no fallback is configured). Use for optional preferences\n * where graceful degradation is preferred.\n *\n * The four built-in middlewares (`customSitePreferencesMiddleware`, etc.) override\n * this default to `'fallback'` so the storefront stays up during transient outages,\n * and expose `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` as an opt-in escape hatch.\n */\n onUnavailable?: 'throw' | 'fallback';\n /**\n * Value to populate the context with when `onUnavailable === 'fallback'` and the data\n * store fetch fails. Either a constant or a function that derives the value from the\n * router context (useful for fallbacks that need request-scoped information). When\n * omitted, the middleware leaves the context unset on failure (downstream consumers\n * see the context's default value, typically `null`).\n */\n fallbackValue?: T | ((context: Readonly<RouterContextProvider>) => T);\n};\n\n/**\n * Creates a typed React Router context for data store entries.\n *\n * Initializes the context with `null` so middleware can populate it during requests.\n *\n * @returns React Router context key for data store values\n */\nexport function createDataStoreContext<T>(): DataStoreContextKey<T> {\n return createContext<T | null>(null);\n}\n\n/**\n * Creates a React Router middleware that fetches a single MRT data store entry on every\n * request and stores the resulting value in the supplied router context.\n *\n * Failure handling is controlled by `options.onUnavailable`:\n * - `'throw'` (default for the factory): rethrow `DataStoreUnavailableError` and\n * `DataStoreServiceError` with a stable error message. Fail-fast — the request errors out.\n * - `'fallback'`: log a warning and resolve to `options.fallbackValue` when configured, or\n * to the missing state (context not populated) when no `fallbackValue` is provided. The\n * request continues without crashing the middleware chain.\n *\n * `DataStoreNotFoundError` is always treated as \"missing\" (warn, do not populate context),\n * regardless of `onUnavailable` — a not-found entry is an expected steady-state for\n * features that haven't been published yet, not a service failure.\n *\n * Errors thrown from `options.transform` propagate to the caller — they indicate a\n * programmer error in the middleware definition, not data-store unavailability.\n *\n * @param options - See {@link DataStoreMiddlewareOptions}.\n * @returns React Router middleware for server requests.\n *\n * @env AWS_REGION (required): AWS region for the data store table (e.g., `us-east-1`).\n * @env MOBIFY_PROPERTY_ID (required): MRT property identifier.\n * @env DEPLOY_TARGET (required): MRT deploy target (e.g., `production`).\n */\nexport function createDataStoreMiddleware<T>(options: DataStoreMiddlewareOptions<T>): MiddlewareFunction<Response> {\n const { entryKey, context: contextKey, onUnavailable = 'throw', fallbackValue } = options;\n const transform = options.transform ?? ((value: Record<string, unknown>) => value as T);\n\n const dataStoreMiddleware: MiddlewareFunction<Response> = async ({ context }, next) => {\n const resolvedEntryKey = typeof entryKey === 'function' ? entryKey(context) : entryKey;\n const result = await loadDataStoreEntry({\n entryKey: resolvedEntryKey,\n context,\n transform,\n onUnavailable,\n fallbackValue,\n });\n\n if (result.state === 'value' || result.state === 'fallback') {\n context.set(contextKey, result.value);\n }\n\n return next();\n };\n\n return dataStoreMiddleware;\n}\n\n/**\n * Lazy variant of {@link createDataStoreMiddleware}. Instead of fetching the\n * entry up-front during middleware execution, this stores a memoized loader\n * in the router context. Consumers call {@link readLazyDataStoreEntry} to\n * trigger the fetch on demand — pages that never read the value never pay\n * for the data-store call.\n *\n * Repeated reads within the same request share the in-flight promise so\n * the entry is fetched at most once per request.\n *\n * Failure handling matches the eager variant: `onUnavailable` and\n * `fallbackValue` are honored when the underlying fetch fails. The fallback\n * value (or `null` for the missing state) surfaces through\n * {@link readLazyDataStoreEntry}.\n *\n * Use this for entries that only a subset of routes consume (e.g. config\n * read by a single feature) rather than entries needed on every request.\n */\nexport function createLazyDataStoreMiddleware<T>(options: DataStoreMiddlewareOptions<T>): MiddlewareFunction<Response> {\n const { entryKey, context: contextKey, onUnavailable = 'throw', fallbackValue } = options;\n const transform = options.transform ?? ((value: Record<string, unknown>) => value as T);\n\n const lazyMiddleware: MiddlewareFunction<Response> = async ({ context }, next) => {\n let pending: Promise<T | null> | undefined;\n\n const loader: LazyDataStoreLoader<T> = () => {\n if (!pending) {\n const resolvedEntryKey = typeof entryKey === 'function' ? entryKey(context) : entryKey;\n pending = loadDataStoreEntry({\n entryKey: resolvedEntryKey,\n context,\n transform,\n onUnavailable,\n fallbackValue,\n }).then((result) => (result.state === 'missing' ? null : result.value));\n }\n return pending;\n };\n\n context.set(contextKey as unknown as DataStoreContextKey<LazyDataStoreLoader<T>>, loader);\n\n return next();\n };\n\n return lazyMiddleware;\n}\n\n/**\n * Reads a value populated by {@link createLazyDataStoreMiddleware}. Triggers\n * the underlying data-store fetch on first call and reuses the cached\n * promise on subsequent calls within the same request.\n *\n * Returns `null` when the lazy middleware did not run (no loader in\n * context) or when the entry is missing/invalid.\n */\nexport async function readLazyDataStoreEntry<T>(\n context: Readonly<RouterContextProvider>,\n contextKey: DataStoreContextKey<T>\n): Promise<T | null> {\n const loader = context.get(contextKey as unknown as DataStoreContextKey<LazyDataStoreLoader<T>>);\n if (typeof loader !== 'function') return null;\n return loader();\n}\n\ntype LazyDataStoreLoader<T> = () => Promise<T | null>;\n\ntype LoadResult<T> = { state: 'value'; value: T } | { state: 'fallback'; value: T } | { state: 'missing' };\n\n/**\n * Internal helper shared by the eager and lazy middleware factories.\n * Performs the fetch + transform pipeline and resolves all three error\n * paths (unavailable / not-found / service-error) consistently. Returns a\n * tagged result so callers can decide whether to populate the context\n * synchronously (eager middleware) or hand the value back to a lazy reader.\n */\nasync function loadDataStoreEntry<T>(args: {\n entryKey: string;\n context: Readonly<RouterContextProvider>;\n transform: (value: Record<string, unknown>) => T;\n onUnavailable: 'throw' | 'fallback';\n fallbackValue: T | ((context: Readonly<RouterContextProvider>) => T) | undefined;\n}): Promise<LoadResult<T>> {\n const { entryKey, context, transform, onUnavailable, fallbackValue } = args;\n const logger = getDataStoreLogger(context);\n\n try {\n const entry = await getDataStoreEntry(entryKey);\n\n if (!entry?.value || typeof entry.value !== 'object') {\n logger.warn(`Data store entry '${entryKey}' not found or invalid.`, { entryKey });\n return { state: 'missing' };\n }\n\n return { state: 'value', value: transform(entry.value as Record<string, unknown>) };\n } catch (error) {\n if (error instanceof DataStoreNotFoundError) {\n logger.warn(`Data store entry '${entryKey}' not found.`, { entryKey, error });\n return { state: 'missing' };\n }\n if (error instanceof DataStoreUnavailableError || error instanceof DataStoreServiceError) {\n return resolveDataStoreFallback({\n entryKey,\n context,\n error,\n onUnavailable,\n fallbackValue,\n logger,\n });\n }\n throw error;\n }\n}\n\nfunction resolveDataStoreFallback<T>(args: {\n entryKey: string;\n context: Readonly<RouterContextProvider>;\n error: DataStoreUnavailableError | DataStoreServiceError;\n onUnavailable: 'throw' | 'fallback';\n fallbackValue: T | ((context: Readonly<RouterContextProvider>) => T) | undefined;\n logger: DataStoreLogger;\n}): LoadResult<T> {\n const { entryKey, context, error, onUnavailable, fallbackValue, logger } = args;\n const reason = error instanceof DataStoreServiceError ? 'service error' : 'unavailable';\n\n if (onUnavailable === 'fallback') {\n if (typeof fallbackValue !== 'undefined') {\n const resolved =\n typeof fallbackValue === 'function'\n ? (fallbackValue as (ctx: Readonly<RouterContextProvider>) => T)(context)\n : fallbackValue;\n logger.warn(`Data store ${reason} for '${entryKey}'. Using configured fallback value.`, {\n entryKey,\n reason,\n error,\n });\n return { state: 'fallback', value: resolved };\n }\n logger.warn(`Data store ${reason} for '${entryKey}'. No fallback configured; treating entry as missing.`, {\n entryKey,\n reason,\n error,\n });\n return { state: 'missing' };\n }\n\n if (error instanceof DataStoreUnavailableError) {\n throw new Error('Data store is unavailable. Ensure AWS_REGION, MOBIFY_PROPERTY_ID, and DEPLOY_TARGET are set.');\n }\n throw new Error(`Data store request failed for '${entryKey}'.`);\n}\n\n/**\n * Read a data-store entry through the singleton MRT utilities API.\n * The underlying implementation (production DynamoDB vs development pseudo store)\n * is resolved by `@salesforce/mrt-utilities/data-store` export conditions.\n *\n * @param key - Data-store entry key\n * @returns Data-store entry or null when missing/invalid shape\n */\nexport async function getDataStoreEntry<TValue = unknown>(key: string): Promise<DataStoreEntry<TValue> | null> {\n const entry = (await DataStore.getDataStore().getEntry(key)) as DataStoreEntry<TValue> | undefined;\n if (!entry || typeof entry !== 'object') {\n return null;\n }\n return entry;\n}\n\n/**\n * Creates an entryKey function that prefixes the given suffix with the current site ID.\n *\n * @param suffix - The entry key suffix (e.g., \"custom-site-preferences\")\n * @returns A function compatible with `DataStoreMiddlewareOptions.entryKey`\n */\nexport function prefixWithSiteId(suffix: string): (context: Readonly<RouterContextProvider>) => string {\n return (context) => {\n const siteId = context.get(siteContext)?.site?.id;\n if (!siteId)\n throw new Error('Site id not found. Ensure site context middleware runs before data-store middleware.');\n return `${siteId}-${suffix}`;\n };\n}\n","/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { RouterContextProvider } from 'react-router';\nimport { getDataStoreLogger } from '../logger-context';\nimport { createDataStoreContext, createDataStoreMiddleware, prefixWithSiteId } from '../utils';\n\nexport type SitePreferences = Record<string, unknown>;\n\nexport const DEFAULT_SITE_PREFERENCES_KEY = 'site-preferences';\nexport const sitePreferencesContext = createDataStoreContext<SitePreferences>();\n\n/**\n * Read site preferences from router context.\n *\n * @param context - Router context provider\n * @returns Site preferences data stored by data-store middleware\n */\nexport function getSitePreferences(context: Readonly<RouterContextProvider>): SitePreferences {\n const data = context.get(sitePreferencesContext);\n if (!data) {\n getDataStoreLogger(context).warn(\n 'Data store context not found. Ensure data-store middleware runs before loaders and the required env vars are set.'\n );\n return {};\n }\n return data;\n}\n\n/**\n * Middleware that reads the site-scoped `custom-site-preferences` entry from the MRT data\n * store and stores it in {@link sitePreferencesContext}. The entry key is prefixed with\n * the current site id (e.g. `acme-custom-site-preferences`).\n *\n * Defaults to graceful degradation: if the data store is unavailable or returns a service\n * error, the request continues with `{}` as the preferences value rather than crashing.\n * Set `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back into\n * fail-fast behavior. The env var is read once at module load.\n *\n * Must run after the site-context middleware (so the site id is available for the entry\n * key) and before any loader that calls {@link getSitePreferences}.\n */\nexport const customSitePreferencesMiddleware = createDataStoreMiddleware({\n entryKey: prefixWithSiteId('custom-site-preferences'),\n context: sitePreferencesContext,\n onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === 'throw' ? 'throw' : 'fallback',\n fallbackValue: {},\n});\n","/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { RouterContextProvider } from 'react-router';\nimport { getDataStoreLogger } from '../logger-context';\nimport { createDataStoreContext, createDataStoreMiddleware } from '../utils';\n\nexport type CustomGlobalPreferences = Record<string, unknown>;\n\nexport const DEFAULT_CUSTOM_GLOBAL_PREFERENCES_KEY = 'custom-global-preferences';\nexport const customGlobalPreferencesContext = createDataStoreContext<CustomGlobalPreferences>();\n\n/**\n * Read custom global preferences from router context.\n *\n * @param context - Router context provider\n * @returns Custom global preferences data stored by data-store middleware\n */\nexport function getCustomGlobalPreferences(context: Readonly<RouterContextProvider>): CustomGlobalPreferences {\n const data = context.get(customGlobalPreferencesContext);\n if (!data) {\n getDataStoreLogger(context).warn(\n 'Custom global preferences context not found. Ensure data-store middleware runs before loaders and the required env vars are set.'\n );\n return {};\n }\n return data;\n}\n\n/**\n * Middleware that reads the global `custom-global-preferences` entry from the MRT data\n * store and stores it in {@link customGlobalPreferencesContext}.\n *\n * Defaults to graceful degradation: if the data store is unavailable or returns a service\n * error, the request continues with `{}` as the preferences value rather than crashing.\n * Set `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back into\n * fail-fast behavior. The env var is read once at module load.\n */\nexport const customGlobalPreferencesMiddleware = createDataStoreMiddleware({\n entryKey: DEFAULT_CUSTOM_GLOBAL_PREFERENCES_KEY,\n context: customGlobalPreferencesContext,\n onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === 'throw' ? 'throw' : 'fallback',\n fallbackValue: {},\n});\n","/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { RouterContextProvider } from 'react-router';\nimport { getDataStoreLogger } from '../logger-context';\nimport { createDataStoreContext, createDataStoreMiddleware } from '../utils';\n\n/**\n * OOTB Google Cloud Platform preferences sourced from the MRT data store.\n *\n * Additional fields (e.g. `projectId`, `region`) may be added here as the\n * ECOM MRT sync job expands the `gcp` entry. Consumers should read the\n * object as a whole via `getGcpPreferences`, or use a specific convenience\n * getter like `getGcpApiKey` for a single field.\n */\nexport type GcpPreferences = {\n apiKey: string;\n};\n\nexport const DEFAULT_GCP_PREFERENCES_KEY = 'gcp';\n\n/**\n * Map keys inside the `gcp` data store entry. The ECOM MRT sync job writes\n * to these exact keys; keep in sync with the sync job contract.\n */\nconst API_KEY_MAP_KEY = 'api-key';\n\nexport const gcpPreferencesContext = createDataStoreContext<GcpPreferences>();\n\n/**\n * Read the GCP (Google Cloud Platform) preferences object from router context.\n *\n * The preferences are sourced from the MRT data store entry `gcp`, which is\n * populated only for storefronts connecting to production ECOM instances.\n * In non-production environments, or when the entry is missing, returns an\n * object whose fields are all empty/default.\n *\n * @param context - Router context provider\n * @returns GCP preferences object; fields are empty/default when the entry is unavailable\n */\nexport function getGcpPreferences(context: Readonly<RouterContextProvider>): GcpPreferences {\n const data = context.get(gcpPreferencesContext);\n if (data === null) {\n getDataStoreLogger(context).warn(\n 'GCP preferences context not found. Ensure gcpPreferencesMiddleware runs before loaders, or expect empty values in environments without the MRT data store entry.'\n );\n return { apiKey: '' };\n }\n return data;\n}\n\n/**\n * Convenience getter for the Google Cloud API key alone.\n *\n * Equivalent to `getGcpPreferences(context).apiKey`.\n *\n * @param context - Router context provider\n * @returns The GCP API key, or an empty string when unavailable\n */\nexport function getGcpApiKey(context: Readonly<RouterContextProvider>): string {\n return getGcpPreferences(context).apiKey;\n}\n\n/**\n * Middleware that reads the OOTB GCP preferences from the MRT data store and\n * stores them in the router context. The entry shape is `{ \"api-key\": string, ... }`\n * under data store key `gcp`. Missing/invalid fields coerce to empty/default values.\n *\n * Only available for storefronts connecting to production ECOM instances. When the entry\n * is not synced (e.g. the GCP feature flag is off in ECOM), the underlying fetch surfaces\n * as `DataStoreNotFoundError` and the context is left unset; consumers see the empty\n * default `{ apiKey: '' }` via {@link getGcpPreferences}.\n *\n * Defaults to graceful degradation: if the data store is unavailable or returns a service\n * error, the request continues with `{ apiKey: '' }` rather than crashing. Set\n * `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back into\n * fail-fast behavior. The env var is read once at module load.\n *\n * Must run before any loader/middleware that reads `getGcpPreferences(context)` or\n * `getGcpApiKey(context)`.\n */\nexport const gcpPreferencesMiddleware = createDataStoreMiddleware<GcpPreferences>({\n entryKey: DEFAULT_GCP_PREFERENCES_KEY,\n context: gcpPreferencesContext,\n onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === 'throw' ? 'throw' : 'fallback',\n fallbackValue: { apiKey: '' },\n transform: (value) => {\n const rawKey = value[API_KEY_MAP_KEY];\n return { apiKey: typeof rawKey === 'string' ? rawKey : '' };\n },\n});\n","/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { RouterContextProvider } from 'react-router';\nimport { getDataStoreLogger } from '../logger-context';\nimport { createDataStoreContext, createDataStoreMiddleware, prefixWithSiteId } from '../utils';\n\nexport type LoginPreferences = {\n emailVerificationEnabled?: boolean;\n};\n\nexport const loginPreferencesContext = createDataStoreContext<LoginPreferences>();\n\n/**\n * Read login preferences from router context.\n *\n * @param context - Router context provider\n * @returns Login preferences data stored by data-store middleware\n */\nexport function getLoginPreferences(context: Readonly<RouterContextProvider>): LoginPreferences {\n const data = context.get(loginPreferencesContext);\n if (!data) {\n getDataStoreLogger(context).warn(\n 'Login preferences context not found. Ensure data-store middleware runs before loaders and the required env vars are set.'\n );\n return {};\n }\n return data;\n}\n\n/**\n * Middleware that reads the site-scoped `login-preferences` entry from the MRT data store\n * and stores its `data` field in {@link loginPreferencesContext}. The entry key is\n * prefixed with the current site id (e.g. `acme-login-preferences`).\n *\n * Defaults to graceful degradation: if the data store is unavailable or returns a service\n * error, the request continues with `{ emailVerificationEnabled: false }` rather than\n * crashing. Set `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=throw` in the environment to opt back\n * into fail-fast behavior. The env var is read once at module load.\n *\n * Must run after the site-context middleware (so the site id is available for the entry\n * key) and before any loader that calls {@link getLoginPreferences}.\n */\nexport const loginPreferencesMiddleware = createDataStoreMiddleware<LoginPreferences>({\n entryKey: prefixWithSiteId('login-preferences'),\n context: loginPreferencesContext,\n onUnavailable: process.env.SFNEXT_DATA_STORE_UNAVAILABLE_MODE === 'throw' ? 'throw' : 'fallback',\n fallbackValue: { emailVerificationEnabled: false },\n transform: (value) => value.data as LoginPreferences,\n});\n","/**\n * Copyright 2026 Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport { createDataStoreMiddleware } from './utils';\nexport { createLazyDataStoreMiddleware, readLazyDataStoreEntry } from './utils';\nexport { createDataStoreContext } from './utils';\nexport { getDataStoreEntry } from './utils';\nexport { dataStoreLoggerContext, getDataStoreLogger } from './logger-context';\nexport type { DataStoreLogger } from './logger-context';\nexport { getSitePreferences } from './middleware/custom-site-preferences';\nexport { getCustomGlobalPreferences } from './middleware/custom-global-preferences';\nexport { getGcpApiKey, getGcpPreferences } from './middleware/gcp-preferences';\nexport type { DataStoreMiddlewareOptions } from './utils';\nexport type { SitePreferences } from './middleware/custom-site-preferences';\nexport type { DataStoreContextKey, DataStoreEntryKey } from './utils';\nexport type { DataStoreEntry } from './utils';\nexport type { CustomGlobalPreferences } from './middleware/custom-global-preferences';\nexport { getLoginPreferences } from './middleware/login-preferences';\nexport type { LoginPreferences } from './middleware/login-preferences';\nexport type { GcpPreferences } from './middleware/gcp-preferences';\nexport { DataStore } from '@salesforce/mrt-utilities/data-store';\nexport {\n DataStoreNotFoundError,\n DataStoreServiceError,\n DataStoreUnavailableError,\n} from '@salesforce/mrt-utilities/data-store';\n\nimport { customSitePreferencesMiddleware } from './middleware/custom-site-preferences';\nimport { customGlobalPreferencesMiddleware } from './middleware/custom-global-preferences';\nimport { gcpPreferencesMiddleware } from './middleware/gcp-preferences';\nimport { loginPreferencesMiddleware } from './middleware/login-preferences';\n\nexport const dataStoreMiddleware = [\n customSitePreferencesMiddleware,\n customGlobalPreferencesMiddleware,\n gcpPreferencesMiddleware,\n loginPreferencesMiddleware,\n];\n"],"mappings":"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"}