@commercengine/storefront-sdk-nextjs 0.1.0-alpha.0 → 0.1.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.
- package/README.md +610 -108
- package/dist/client.cjs +430 -0
- package/dist/client.d.cts +138 -0
- package/dist/client.d.ts +138 -0
- package/dist/client.js +398 -0
- package/dist/index.cjs +163 -89
- package/dist/index.d.cts +9 -18
- package/dist/index.d.ts +9 -18
- package/dist/index.js +162 -87
- package/dist/middleware.cjs +66 -0
- package/dist/middleware.d.cts +38 -0
- package/dist/middleware.d.ts +38 -0
- package/dist/middleware.js +39 -0
- package/dist/server-D-pFrx8J.d.cts +105 -0
- package/dist/server-DaDfTjsO.d.cts +103 -0
- package/dist/server-DaDfTjsO.d.ts +103 -0
- package/dist/server-DjlQVC11.d.ts +105 -0
- package/dist/server.cjs +416 -0
- package/dist/server.d.cts +4 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +385 -0
- package/dist/storefront.cjs +402 -0
- package/dist/storefront.d.cts +40 -0
- package/dist/storefront.d.ts +40 -0
- package/dist/storefront.js +376 -0
- package/package.json +18 -8
package/dist/index.js
CHANGED
|
@@ -6,8 +6,11 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
// src/sdk-manager.ts
|
|
9
|
+
import { cache } from "react";
|
|
9
10
|
import {
|
|
10
|
-
StorefrontSDK
|
|
11
|
+
StorefrontSDK,
|
|
12
|
+
MemoryTokenStorage,
|
|
13
|
+
Environment
|
|
11
14
|
} from "@commercengine/storefront-sdk";
|
|
12
15
|
|
|
13
16
|
// src/token-storage.ts
|
|
@@ -116,7 +119,7 @@ var ServerTokenStorage = class {
|
|
|
116
119
|
secure: this.options.secure,
|
|
117
120
|
sameSite: this.options.sameSite?.toLowerCase(),
|
|
118
121
|
httpOnly: false
|
|
119
|
-
//
|
|
122
|
+
// Allow client-side access for SDK flexibility
|
|
120
123
|
});
|
|
121
124
|
} catch (error) {
|
|
122
125
|
console.warn(`Could not set access token on server:`, error);
|
|
@@ -139,7 +142,7 @@ var ServerTokenStorage = class {
|
|
|
139
142
|
secure: this.options.secure,
|
|
140
143
|
sameSite: this.options.sameSite?.toLowerCase(),
|
|
141
144
|
httpOnly: false
|
|
142
|
-
//
|
|
145
|
+
// Allow client-side access for SDK flexibility
|
|
143
146
|
});
|
|
144
147
|
} catch (error) {
|
|
145
148
|
console.warn(`Could not set refresh token on server:`, error);
|
|
@@ -155,88 +158,171 @@ var ServerTokenStorage = class {
|
|
|
155
158
|
}
|
|
156
159
|
};
|
|
157
160
|
|
|
158
|
-
// src/
|
|
159
|
-
var
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
161
|
+
// src/build-token-cache.ts
|
|
162
|
+
var store = /* @__PURE__ */ new Map();
|
|
163
|
+
function isExpired(token) {
|
|
164
|
+
if (!token) return true;
|
|
165
|
+
if (!token.expiresAt) return false;
|
|
166
|
+
return Date.now() > token.expiresAt - 3e4;
|
|
167
|
+
}
|
|
168
|
+
function getCachedToken(key) {
|
|
169
|
+
const token = store.get(key);
|
|
170
|
+
return isExpired(token) ? null : token;
|
|
171
|
+
}
|
|
172
|
+
function setCachedToken(key, token) {
|
|
173
|
+
const expiresAt = token.ttlSeconds != null ? Date.now() + token.ttlSeconds * 1e3 : void 0;
|
|
174
|
+
store.set(key, {
|
|
175
|
+
accessToken: token.accessToken,
|
|
176
|
+
refreshToken: token.refreshToken ?? null,
|
|
177
|
+
expiresAt
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function clearCachedToken(key) {
|
|
181
|
+
store.delete(key);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/build-caching-memory-storage.ts
|
|
185
|
+
var DEFAULT_TTL_SECONDS = 5 * 60;
|
|
186
|
+
var BuildCachingMemoryTokenStorage = class {
|
|
187
|
+
constructor(cacheKey, ttlSeconds = DEFAULT_TTL_SECONDS) {
|
|
188
|
+
this.cacheKey = cacheKey;
|
|
189
|
+
this.ttlSeconds = ttlSeconds;
|
|
190
|
+
this.access = null;
|
|
191
|
+
this.refresh = null;
|
|
178
192
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (!this.config) {
|
|
184
|
-
throw new Error("SDK not initialized. Call initialize() first.");
|
|
193
|
+
async getAccessToken() {
|
|
194
|
+
if (this.access) {
|
|
195
|
+
console.log(`\u{1F535} [BuildCache] Using instance token for key: ${this.cacheKey}`);
|
|
196
|
+
return this.access;
|
|
185
197
|
}
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
const cached = getCachedToken(this.cacheKey);
|
|
199
|
+
if (cached?.accessToken) {
|
|
200
|
+
console.log(`\u{1F7E2} [BuildCache] Using cached token for key: ${this.cacheKey}`);
|
|
201
|
+
this.access = cached.accessToken;
|
|
202
|
+
this.refresh = cached.refreshToken ?? null;
|
|
203
|
+
return this.access;
|
|
188
204
|
}
|
|
189
|
-
|
|
205
|
+
console.log(`\u{1F7E1} [BuildCache] No cached token found for key: ${this.cacheKey}`);
|
|
206
|
+
return null;
|
|
190
207
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return new StorefrontSDK({
|
|
199
|
-
...this.config,
|
|
200
|
-
tokenStorage: new ServerTokenStorage(
|
|
201
|
-
cookieStore,
|
|
202
|
-
this.config.tokenStorageOptions
|
|
203
|
-
)
|
|
208
|
+
async setAccessToken(token) {
|
|
209
|
+
console.log(`\u{1F7E0} [BuildCache] Caching new access token for key: ${this.cacheKey}`);
|
|
210
|
+
this.access = token;
|
|
211
|
+
setCachedToken(this.cacheKey, {
|
|
212
|
+
accessToken: token,
|
|
213
|
+
refreshToken: this.refresh,
|
|
214
|
+
ttlSeconds: this.ttlSeconds
|
|
204
215
|
});
|
|
205
216
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
throw new Error("SDK not initialized. Call initialize() first.");
|
|
209
|
-
}
|
|
210
|
-
return new StorefrontSDK({
|
|
211
|
-
...this.config,
|
|
212
|
-
tokenStorage: new ClientTokenStorage(this.config.tokenStorageOptions)
|
|
213
|
-
});
|
|
217
|
+
async getRefreshToken() {
|
|
218
|
+
return this.refresh;
|
|
214
219
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
async setRefreshToken(token) {
|
|
221
|
+
this.refresh = token;
|
|
222
|
+
setCachedToken(this.cacheKey, {
|
|
223
|
+
accessToken: this.access ?? "",
|
|
224
|
+
refreshToken: token,
|
|
225
|
+
ttlSeconds: this.ttlSeconds
|
|
226
|
+
});
|
|
220
227
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
this.clientSDK = null;
|
|
226
|
-
this.config = null;
|
|
228
|
+
async clearTokens() {
|
|
229
|
+
this.access = null;
|
|
230
|
+
this.refresh = null;
|
|
231
|
+
clearCachedToken(this.cacheKey);
|
|
227
232
|
}
|
|
228
233
|
};
|
|
234
|
+
|
|
235
|
+
// src/sdk-manager.ts
|
|
236
|
+
var globalConfig = null;
|
|
237
|
+
function getEnvConfig() {
|
|
238
|
+
return {
|
|
239
|
+
storeId: process.env.NEXT_PUBLIC_STORE_ID || "",
|
|
240
|
+
environment: process.env.NEXT_PUBLIC_ENVIRONMENT === "production" ? Environment.Production : Environment.Staging,
|
|
241
|
+
apiKey: process.env.NEXT_PUBLIC_API_KEY
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function getConfig() {
|
|
245
|
+
if (globalConfig) {
|
|
246
|
+
return globalConfig;
|
|
247
|
+
}
|
|
248
|
+
return getEnvConfig();
|
|
249
|
+
}
|
|
250
|
+
var clientSDK = null;
|
|
251
|
+
function hasRequestContext() {
|
|
252
|
+
try {
|
|
253
|
+
const { cookies } = __require("next/headers");
|
|
254
|
+
cookies();
|
|
255
|
+
return true;
|
|
256
|
+
} catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function createTokenStorage(cookieStore, options, config) {
|
|
261
|
+
if (typeof window !== "undefined") {
|
|
262
|
+
return new ClientTokenStorage(options);
|
|
263
|
+
}
|
|
264
|
+
if (cookieStore) {
|
|
265
|
+
return new ServerTokenStorage(cookieStore, options);
|
|
266
|
+
}
|
|
267
|
+
const shouldCache = process.env.NEXT_BUILD_CACHE_TOKENS === "true";
|
|
268
|
+
if (shouldCache && config) {
|
|
269
|
+
const cacheKey = `${config.storeId}:${config.environment || "production"}`;
|
|
270
|
+
console.log(`\u{1F680} [BuildCache] Using BuildCachingMemoryTokenStorage with key: ${cacheKey}`);
|
|
271
|
+
return new BuildCachingMemoryTokenStorage(cacheKey);
|
|
272
|
+
}
|
|
273
|
+
console.log(`\u{1F504} [Build] Using standard MemoryTokenStorage (caching disabled)`);
|
|
274
|
+
return new MemoryTokenStorage();
|
|
275
|
+
}
|
|
276
|
+
var getServerSDKCached = cache((cookieStore) => {
|
|
277
|
+
const config = getEnvConfig();
|
|
278
|
+
return new StorefrontSDK({
|
|
279
|
+
...config,
|
|
280
|
+
tokenStorage: createTokenStorage(
|
|
281
|
+
cookieStore,
|
|
282
|
+
config.tokenStorageOptions,
|
|
283
|
+
config
|
|
284
|
+
)
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
var buildTimeSDK = null;
|
|
288
|
+
function getBuildTimeSDK() {
|
|
289
|
+
const config = getEnvConfig();
|
|
290
|
+
if (!buildTimeSDK) {
|
|
291
|
+
buildTimeSDK = new StorefrontSDK({
|
|
292
|
+
...config,
|
|
293
|
+
tokenStorage: createTokenStorage(
|
|
294
|
+
void 0,
|
|
295
|
+
config.tokenStorageOptions,
|
|
296
|
+
config
|
|
297
|
+
)
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
return buildTimeSDK;
|
|
301
|
+
}
|
|
229
302
|
function getStorefrontSDK(cookieStore) {
|
|
230
|
-
const manager = NextJSSDKManager.getInstance();
|
|
231
303
|
if (typeof window !== "undefined") {
|
|
232
304
|
if (cookieStore) {
|
|
233
305
|
console.warn(
|
|
234
306
|
"Cookie store passed in client environment - this will be ignored"
|
|
235
307
|
);
|
|
236
308
|
}
|
|
237
|
-
|
|
309
|
+
const config = getConfig();
|
|
310
|
+
if (!clientSDK) {
|
|
311
|
+
clientSDK = new StorefrontSDK({
|
|
312
|
+
...config,
|
|
313
|
+
tokenStorage: createTokenStorage(
|
|
314
|
+
void 0,
|
|
315
|
+
config.tokenStorageOptions,
|
|
316
|
+
config
|
|
317
|
+
)
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
return clientSDK;
|
|
238
321
|
}
|
|
239
|
-
if (
|
|
322
|
+
if (cookieStore) {
|
|
323
|
+
return getServerSDKCached(cookieStore);
|
|
324
|
+
}
|
|
325
|
+
if (hasRequestContext()) {
|
|
240
326
|
let autoDetectMessage = "";
|
|
241
327
|
try {
|
|
242
328
|
__require.resolve("next/headers");
|
|
@@ -245,7 +331,7 @@ function getStorefrontSDK(cookieStore) {
|
|
|
245
331
|
\u{1F50D} Auto-detection attempted but failed. You may be in:
|
|
246
332
|
- Server Action (use: const sdk = getStorefrontSDK(await cookies()))
|
|
247
333
|
- API Route (use: const sdk = getStorefrontSDK(cookies()))
|
|
248
|
-
-
|
|
334
|
+
- Server Component in App Router (use: const sdk = getStorefrontSDK(cookies()))
|
|
249
335
|
`;
|
|
250
336
|
} catch {
|
|
251
337
|
autoDetectMessage = `
|
|
@@ -266,7 +352,7 @@ import { cookies } from 'next/headers';
|
|
|
266
352
|
// Server Actions & Route Handlers
|
|
267
353
|
const sdk = getStorefrontSDK(await cookies());
|
|
268
354
|
|
|
269
|
-
// API Routes (
|
|
355
|
+
// API Routes & Server Components (App Router)
|
|
270
356
|
const sdk = getStorefrontSDK(cookies());
|
|
271
357
|
|
|
272
358
|
\u274C Your current usage:
|
|
@@ -276,30 +362,19 @@ This is required for server-side token access.
|
|
|
276
362
|
`.trim()
|
|
277
363
|
);
|
|
278
364
|
}
|
|
279
|
-
return
|
|
280
|
-
}
|
|
281
|
-
function initializeStorefrontSDK(config) {
|
|
282
|
-
const manager = NextJSSDKManager.getInstance();
|
|
283
|
-
manager.initialize(config);
|
|
365
|
+
return getBuildTimeSDK();
|
|
284
366
|
}
|
|
285
367
|
|
|
286
|
-
// src/
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
config
|
|
290
|
-
}) {
|
|
291
|
-
useEffect(() => {
|
|
292
|
-
initializeStorefrontSDK(config);
|
|
293
|
-
}, [config]);
|
|
294
|
-
return null;
|
|
368
|
+
// src/storefront.ts
|
|
369
|
+
function storefront(cookieStore) {
|
|
370
|
+
return getStorefrontSDK(cookieStore);
|
|
295
371
|
}
|
|
296
372
|
|
|
297
373
|
// src/index.ts
|
|
298
|
-
|
|
374
|
+
export * from "@commercengine/storefront-sdk";
|
|
299
375
|
export {
|
|
300
376
|
ClientTokenStorage,
|
|
301
|
-
Environment,
|
|
302
377
|
ServerTokenStorage,
|
|
303
|
-
|
|
304
|
-
|
|
378
|
+
getStorefrontSDK,
|
|
379
|
+
storefront
|
|
305
380
|
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/middleware.ts
|
|
21
|
+
var middleware_exports = {};
|
|
22
|
+
__export(middleware_exports, {
|
|
23
|
+
ensureStorefrontTokens: () => ensureStorefrontTokens
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(middleware_exports);
|
|
26
|
+
|
|
27
|
+
// src/middleware-helper.ts
|
|
28
|
+
async function ensureStorefrontTokens(reqCookies, resCookies, opts) {
|
|
29
|
+
const prefix = opts.cookiePrefix ?? "ce_";
|
|
30
|
+
const ACCESS = `${prefix}access_token`;
|
|
31
|
+
const existingAccess = reqCookies.get(ACCESS)?.value;
|
|
32
|
+
if (existingAccess) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const resp = await fetch(`${opts.baseUrl}/auth/anonymous`, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
headers: {
|
|
39
|
+
"Content-Type": "application/json",
|
|
40
|
+
...opts.apiKey ? { "X-Api-Key": opts.apiKey } : {}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (!resp.ok) return false;
|
|
44
|
+
const data = await resp.json();
|
|
45
|
+
const content = data?.content;
|
|
46
|
+
if (!content?.access_token || !content?.refresh_token) return false;
|
|
47
|
+
const cookieDefaults = {
|
|
48
|
+
path: "/",
|
|
49
|
+
httpOnly: false,
|
|
50
|
+
sameSite: "lax",
|
|
51
|
+
secure: opts.cookieOptions?.secure ?? false,
|
|
52
|
+
maxAge: 30 * 24 * 60 * 60
|
|
53
|
+
// 30 days
|
|
54
|
+
};
|
|
55
|
+
const finalOpts = { ...cookieDefaults, ...opts.cookieOptions || {} };
|
|
56
|
+
resCookies.set(ACCESS, content.access_token, finalOpts);
|
|
57
|
+
resCookies.set(`${prefix}refresh_token`, content.refresh_token, finalOpts);
|
|
58
|
+
return true;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
64
|
+
0 && (module.exports = {
|
|
65
|
+
ensureStorefrontTokens
|
|
66
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal cookie interface compatible with Next.js middleware cookies API.
|
|
3
|
+
*/
|
|
4
|
+
interface NextCookiesLike {
|
|
5
|
+
get: (name: string) => {
|
|
6
|
+
value: string;
|
|
7
|
+
} | undefined;
|
|
8
|
+
set: (name: string, value: string, options?: {
|
|
9
|
+
maxAge?: number;
|
|
10
|
+
path?: string;
|
|
11
|
+
domain?: string;
|
|
12
|
+
secure?: boolean;
|
|
13
|
+
sameSite?: "strict" | "lax" | "none" | (string & {});
|
|
14
|
+
httpOnly?: boolean;
|
|
15
|
+
}) => any;
|
|
16
|
+
}
|
|
17
|
+
interface EnsureTokensOptions {
|
|
18
|
+
baseUrl: string;
|
|
19
|
+
apiKey?: string;
|
|
20
|
+
cookiePrefix?: string;
|
|
21
|
+
cookieOptions?: {
|
|
22
|
+
maxAge?: number;
|
|
23
|
+
path?: string;
|
|
24
|
+
domain?: string;
|
|
25
|
+
secure?: boolean;
|
|
26
|
+
sameSite?: "strict" | "lax" | "none";
|
|
27
|
+
httpOnly?: boolean;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Pre-seed anonymous tokens in Next.js middleware when missing.
|
|
32
|
+
* Call this early to ensure SSR and client share the same session.
|
|
33
|
+
*
|
|
34
|
+
* Returns true if tokens were set on the response, false otherwise.
|
|
35
|
+
*/
|
|
36
|
+
declare function ensureStorefrontTokens(reqCookies: NextCookiesLike, resCookies: NextCookiesLike, opts: EnsureTokensOptions): Promise<boolean>;
|
|
37
|
+
|
|
38
|
+
export { type EnsureTokensOptions, type NextCookiesLike, ensureStorefrontTokens };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal cookie interface compatible with Next.js middleware cookies API.
|
|
3
|
+
*/
|
|
4
|
+
interface NextCookiesLike {
|
|
5
|
+
get: (name: string) => {
|
|
6
|
+
value: string;
|
|
7
|
+
} | undefined;
|
|
8
|
+
set: (name: string, value: string, options?: {
|
|
9
|
+
maxAge?: number;
|
|
10
|
+
path?: string;
|
|
11
|
+
domain?: string;
|
|
12
|
+
secure?: boolean;
|
|
13
|
+
sameSite?: "strict" | "lax" | "none" | (string & {});
|
|
14
|
+
httpOnly?: boolean;
|
|
15
|
+
}) => any;
|
|
16
|
+
}
|
|
17
|
+
interface EnsureTokensOptions {
|
|
18
|
+
baseUrl: string;
|
|
19
|
+
apiKey?: string;
|
|
20
|
+
cookiePrefix?: string;
|
|
21
|
+
cookieOptions?: {
|
|
22
|
+
maxAge?: number;
|
|
23
|
+
path?: string;
|
|
24
|
+
domain?: string;
|
|
25
|
+
secure?: boolean;
|
|
26
|
+
sameSite?: "strict" | "lax" | "none";
|
|
27
|
+
httpOnly?: boolean;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Pre-seed anonymous tokens in Next.js middleware when missing.
|
|
32
|
+
* Call this early to ensure SSR and client share the same session.
|
|
33
|
+
*
|
|
34
|
+
* Returns true if tokens were set on the response, false otherwise.
|
|
35
|
+
*/
|
|
36
|
+
declare function ensureStorefrontTokens(reqCookies: NextCookiesLike, resCookies: NextCookiesLike, opts: EnsureTokensOptions): Promise<boolean>;
|
|
37
|
+
|
|
38
|
+
export { type EnsureTokensOptions, type NextCookiesLike, ensureStorefrontTokens };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// src/middleware-helper.ts
|
|
2
|
+
async function ensureStorefrontTokens(reqCookies, resCookies, opts) {
|
|
3
|
+
const prefix = opts.cookiePrefix ?? "ce_";
|
|
4
|
+
const ACCESS = `${prefix}access_token`;
|
|
5
|
+
const existingAccess = reqCookies.get(ACCESS)?.value;
|
|
6
|
+
if (existingAccess) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
const resp = await fetch(`${opts.baseUrl}/auth/anonymous`, {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: {
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
...opts.apiKey ? { "X-Api-Key": opts.apiKey } : {}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
if (!resp.ok) return false;
|
|
18
|
+
const data = await resp.json();
|
|
19
|
+
const content = data?.content;
|
|
20
|
+
if (!content?.access_token || !content?.refresh_token) return false;
|
|
21
|
+
const cookieDefaults = {
|
|
22
|
+
path: "/",
|
|
23
|
+
httpOnly: false,
|
|
24
|
+
sameSite: "lax",
|
|
25
|
+
secure: opts.cookieOptions?.secure ?? false,
|
|
26
|
+
maxAge: 30 * 24 * 60 * 60
|
|
27
|
+
// 30 days
|
|
28
|
+
};
|
|
29
|
+
const finalOpts = { ...cookieDefaults, ...opts.cookieOptions || {} };
|
|
30
|
+
resCookies.set(ACCESS, content.access_token, finalOpts);
|
|
31
|
+
resCookies.set(`${prefix}refresh_token`, content.refresh_token, finalOpts);
|
|
32
|
+
return true;
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
ensureStorefrontTokens
|
|
39
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { TokenStorage, StorefrontSDK, StorefrontSDKOptions } from '@commercengine/storefront-sdk';
|
|
2
|
+
import './storefront.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for NextJSTokenStorage
|
|
6
|
+
*/
|
|
7
|
+
interface NextJSTokenStorageOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Prefix for cookie names (default: "ce_")
|
|
10
|
+
*/
|
|
11
|
+
prefix?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Maximum age of cookies in seconds (default: 30 days)
|
|
14
|
+
*/
|
|
15
|
+
maxAge?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Cookie path (default: "/")
|
|
18
|
+
*/
|
|
19
|
+
path?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Cookie domain (default: current domain)
|
|
22
|
+
*/
|
|
23
|
+
domain?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Whether cookies should be secure (default: auto-detect based on environment)
|
|
26
|
+
*/
|
|
27
|
+
secure?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* SameSite cookie attribute (default: "Lax")
|
|
30
|
+
*/
|
|
31
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Client-side token storage that uses document.cookie
|
|
35
|
+
*/
|
|
36
|
+
declare class ClientTokenStorage implements TokenStorage {
|
|
37
|
+
private accessTokenKey;
|
|
38
|
+
private refreshTokenKey;
|
|
39
|
+
private options;
|
|
40
|
+
constructor(options?: NextJSTokenStorageOptions);
|
|
41
|
+
getAccessToken(): Promise<string | null>;
|
|
42
|
+
setAccessToken(token: string): Promise<void>;
|
|
43
|
+
getRefreshToken(): Promise<string | null>;
|
|
44
|
+
setRefreshToken(token: string): Promise<void>;
|
|
45
|
+
clearTokens(): Promise<void>;
|
|
46
|
+
private getCookie;
|
|
47
|
+
private setCookie;
|
|
48
|
+
private deleteCookie;
|
|
49
|
+
}
|
|
50
|
+
type NextCookieStore$1 = {
|
|
51
|
+
get: (name: string) => {
|
|
52
|
+
value: string;
|
|
53
|
+
} | undefined;
|
|
54
|
+
set: (name: string, value: string, options?: any) => void;
|
|
55
|
+
delete: (name: string) => void;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Server-side token storage that uses Next.js cookies API
|
|
59
|
+
*/
|
|
60
|
+
declare class ServerTokenStorage implements TokenStorage {
|
|
61
|
+
private accessTokenKey;
|
|
62
|
+
private refreshTokenKey;
|
|
63
|
+
private options;
|
|
64
|
+
private cookieStore;
|
|
65
|
+
constructor(cookieStore: NextCookieStore$1, options?: NextJSTokenStorageOptions);
|
|
66
|
+
getAccessToken(): Promise<string | null>;
|
|
67
|
+
setAccessToken(token: string): Promise<void>;
|
|
68
|
+
getRefreshToken(): Promise<string | null>;
|
|
69
|
+
setRefreshToken(token: string): Promise<void>;
|
|
70
|
+
clearTokens(): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Configuration for the NextJS SDK wrapper
|
|
75
|
+
*/
|
|
76
|
+
interface NextJSSDKConfig extends Omit<StorefrontSDKOptions, "tokenStorage"> {
|
|
77
|
+
/**
|
|
78
|
+
* Token storage configuration options
|
|
79
|
+
*/
|
|
80
|
+
tokenStorageOptions?: NextJSTokenStorageOptions;
|
|
81
|
+
}
|
|
82
|
+
type NextCookieStore = {
|
|
83
|
+
get: (name: string) => {
|
|
84
|
+
value: string;
|
|
85
|
+
} | undefined;
|
|
86
|
+
set: (name: string, value: string, options?: any) => void;
|
|
87
|
+
delete: (name: string) => void;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Smart SDK getter that automatically detects environment
|
|
91
|
+
*
|
|
92
|
+
* Usage:
|
|
93
|
+
* - Client-side: getStorefrontSDK()
|
|
94
|
+
* - Server-side with request context: getStorefrontSDK(await cookies())
|
|
95
|
+
* - SSG/ISR (no request context): getStorefrontSDK() (uses memory storage)
|
|
96
|
+
*/
|
|
97
|
+
declare function getStorefrontSDK(): StorefrontSDK;
|
|
98
|
+
declare function getStorefrontSDK(cookieStore: NextCookieStore): StorefrontSDK;
|
|
99
|
+
/**
|
|
100
|
+
* Initialize the SDK with configuration (internal use)
|
|
101
|
+
* This should be called once in your app via StorefrontSDKInitializer
|
|
102
|
+
*/
|
|
103
|
+
declare function initializeStorefrontSDK(config: NextJSSDKConfig): void;
|
|
104
|
+
|
|
105
|
+
export { ClientTokenStorage as C, type NextJSSDKConfig as N, ServerTokenStorage as S, type NextJSTokenStorageOptions as a, getStorefrontSDK as g, initializeStorefrontSDK as i };
|