@feelflow/ffid-sdk 1.7.3 → 1.9.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/README.md +6 -1
- package/dist/{chunk-LLOXOE37.cjs → chunk-CBYBTBKA.cjs} +117 -20
- package/dist/{chunk-SNARMHI7.js → chunk-H5JRKOD7.js} +117 -20
- package/dist/components/index.cjs +7 -7
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/{index-ea8WAh39.d.cts → index-CTvhqdrH.d.cts} +35 -1
- package/dist/{index-ea8WAh39.d.ts → index-CTvhqdrH.d.ts} +35 -1
- package/dist/index.cjs +64 -22
- package/dist/index.d.cts +26 -3
- package/dist/index.d.ts +26 -3
- package/dist/index.js +43 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,10 @@ yarn add @feelflow/ffid-sdk
|
|
|
17
17
|
pnpm add @feelflow/ffid-sdk
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
## 統合ガイド
|
|
21
|
+
|
|
22
|
+
サービスを FFID Platform に統合する詳細なガイドは **[Integration Guide](./docs/INTEGRATION_GUIDE.md)** を参照してください。OAuth フロー、フロントエンド/バックエンド実装パターン、セキュリティチェックリスト、アンチパターン集を網羅しています。
|
|
23
|
+
|
|
20
24
|
## クイックスタート
|
|
21
25
|
|
|
22
26
|
### 1. プロバイダーを設定(5行で完了!)
|
|
@@ -263,9 +267,10 @@ token mode では SDK は `/api/v1/oauth/userinfo` を呼び出し、基本プ
|
|
|
263
267
|
|
|
264
268
|
```ts
|
|
265
269
|
interface FFIDOAuthUserInfoSubscription {
|
|
270
|
+
subscriptionId: string | null
|
|
266
271
|
status: 'trialing' | 'active' | 'past_due' | 'canceled' | 'paused' | null
|
|
267
272
|
planCode: string | null
|
|
268
|
-
seatModel: 'organization' |
|
|
273
|
+
seatModel: 'organization' | null
|
|
269
274
|
memberRole: 'owner' | 'admin' | 'member' | 'viewer' | null
|
|
270
275
|
organizationId: string | null
|
|
271
276
|
}
|
|
@@ -238,8 +238,11 @@ function createJwtVerifier(deps) {
|
|
|
238
238
|
|
|
239
239
|
// src/client/verify-access-token.ts
|
|
240
240
|
var OAUTH_INTROSPECT_ENDPOINT = "/api/v1/oauth/introspect";
|
|
241
|
+
var CACHE_KEY_PREFIX = "ffid:introspect:";
|
|
242
|
+
var HEX_BASE = 16;
|
|
243
|
+
var HEX_BYTE_WIDTH = 2;
|
|
241
244
|
function createVerifyAccessToken(deps) {
|
|
242
|
-
const { authMode, baseUrl, serviceCode, serviceApiKey, verifyStrategy, logger, createError, errorCodes } = deps;
|
|
245
|
+
const { authMode, baseUrl, serviceCode, serviceApiKey, verifyStrategy, logger, createError, errorCodes, cache, timeout } = deps;
|
|
243
246
|
let jwtVerify2 = null;
|
|
244
247
|
function getJwtVerifier() {
|
|
245
248
|
if (!jwtVerify2) {
|
|
@@ -286,17 +289,33 @@ function createVerifyAccessToken(deps) {
|
|
|
286
289
|
}
|
|
287
290
|
const url = `${baseUrl}${OAUTH_INTROSPECT_ENDPOINT}`;
|
|
288
291
|
logger.debug("Verifying access token:", url);
|
|
292
|
+
const cacheKey = await buildCacheKey(accessToken);
|
|
293
|
+
if (cache) {
|
|
294
|
+
try {
|
|
295
|
+
const cached = await cache.adapter.get(cacheKey);
|
|
296
|
+
if (cached && typeof cached === "object" && "sub" in cached) {
|
|
297
|
+
logger.debug("Cache hit for introspect result");
|
|
298
|
+
return { data: cached };
|
|
299
|
+
}
|
|
300
|
+
} catch (cacheError) {
|
|
301
|
+
logger.warn("Cache read failed, falling back to API call:", cacheError);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const fetchOptions = {
|
|
305
|
+
method: "POST",
|
|
306
|
+
credentials: "omit",
|
|
307
|
+
headers: {
|
|
308
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
309
|
+
"X-Service-Api-Key": serviceApiKey
|
|
310
|
+
},
|
|
311
|
+
body: new URLSearchParams({ token: accessToken }).toString()
|
|
312
|
+
};
|
|
313
|
+
if (timeout !== void 0) {
|
|
314
|
+
fetchOptions.signal = AbortSignal.timeout(timeout);
|
|
315
|
+
}
|
|
289
316
|
let response;
|
|
290
317
|
try {
|
|
291
|
-
response = await fetch(url,
|
|
292
|
-
method: "POST",
|
|
293
|
-
credentials: "omit",
|
|
294
|
-
headers: {
|
|
295
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
296
|
-
"X-Service-Api-Key": serviceApiKey
|
|
297
|
-
},
|
|
298
|
-
body: new URLSearchParams({ token: accessToken }).toString()
|
|
299
|
-
});
|
|
318
|
+
response = await fetch(url, fetchOptions);
|
|
300
319
|
} catch (error) {
|
|
301
320
|
logger.error("Network error during token verification:", error);
|
|
302
321
|
return {
|
|
@@ -362,7 +381,26 @@ function createVerifyAccessToken(deps) {
|
|
|
362
381
|
organization_id: introspectResponse.subscription.organization_id
|
|
363
382
|
}
|
|
364
383
|
} : base;
|
|
365
|
-
|
|
384
|
+
const userinfo = normalizeUserinfo(raw);
|
|
385
|
+
if (cache) {
|
|
386
|
+
try {
|
|
387
|
+
await cache.adapter.set(cacheKey, userinfo, cache.ttl);
|
|
388
|
+
} catch (cacheError) {
|
|
389
|
+
logger.warn("Cache write failed (result still returned):", cacheError);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return { data: userinfo };
|
|
393
|
+
}
|
|
394
|
+
async function buildCacheKey(token) {
|
|
395
|
+
if (typeof globalThis.crypto?.subtle?.digest === "function") {
|
|
396
|
+
const encoder = new TextEncoder();
|
|
397
|
+
const data = encoder.encode(token);
|
|
398
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
399
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
400
|
+
const hashHex = hashArray.map((b) => b.toString(HEX_BASE).padStart(HEX_BYTE_WIDTH, "0")).join("");
|
|
401
|
+
return CACHE_KEY_PREFIX + hashHex;
|
|
402
|
+
}
|
|
403
|
+
return CACHE_KEY_PREFIX + token;
|
|
366
404
|
}
|
|
367
405
|
return verifyAccessToken;
|
|
368
406
|
}
|
|
@@ -414,6 +452,43 @@ function createBillingMethods(deps) {
|
|
|
414
452
|
return { createCheckoutSession, createPortalSession };
|
|
415
453
|
}
|
|
416
454
|
|
|
455
|
+
// src/client/version-check.ts
|
|
456
|
+
var SDK_VERSION = "1.9.0";
|
|
457
|
+
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
458
|
+
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
459
|
+
var LATEST_VERSION_HEADER = "X-FFID-SDK-Latest-Version";
|
|
460
|
+
var SEMVER_PATTERN = /^\d+(\.\d+)*$/;
|
|
461
|
+
var _versionWarningShown = false;
|
|
462
|
+
function compareSemver(a, b) {
|
|
463
|
+
const cleanA = a.replace(/^v/, "");
|
|
464
|
+
const cleanB = b.replace(/^v/, "");
|
|
465
|
+
if (!SEMVER_PATTERN.test(cleanA) || !SEMVER_PATTERN.test(cleanB)) return 0;
|
|
466
|
+
const partsA = cleanA.split(".").map(Number);
|
|
467
|
+
const partsB = cleanB.split(".").map(Number);
|
|
468
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
469
|
+
for (let i = 0; i < maxLen; i++) {
|
|
470
|
+
const numA = partsA[i] ?? 0;
|
|
471
|
+
const numB = partsB[i] ?? 0;
|
|
472
|
+
if (numA < numB) return -1;
|
|
473
|
+
if (numA > numB) return 1;
|
|
474
|
+
}
|
|
475
|
+
return 0;
|
|
476
|
+
}
|
|
477
|
+
function checkVersionHeader(response, logger) {
|
|
478
|
+
if (_versionWarningShown) return;
|
|
479
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
|
|
480
|
+
if (!response.headers?.get) return;
|
|
481
|
+
const latestVersion = response.headers.get(LATEST_VERSION_HEADER);
|
|
482
|
+
if (!latestVersion) return;
|
|
483
|
+
if (compareSemver(SDK_VERSION, latestVersion) < 0) {
|
|
484
|
+
_versionWarningShown = true;
|
|
485
|
+
logger.warn(
|
|
486
|
+
`\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3\u304C\u5229\u7528\u53EF\u80FD\u3067\u3059: v${latestVersion} (\u73FE\u5728: v${SDK_VERSION})
|
|
487
|
+
npm install @feelflow/ffid-sdk@latest \u3067\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3067\u304D\u307E\u3059`
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
417
492
|
// src/client/ffid-client.ts
|
|
418
493
|
var NO_CONTENT_STATUS = 204;
|
|
419
494
|
var SESSION_ENDPOINT = "/api/v1/auth/session";
|
|
@@ -427,7 +502,7 @@ var SDK_LOG_PREFIX = "[FFID SDK]";
|
|
|
427
502
|
var MS_PER_SECOND = 1e3;
|
|
428
503
|
var UNAUTHORIZED_STATUS = 401;
|
|
429
504
|
var STATE_RANDOM_BYTES = 16;
|
|
430
|
-
var
|
|
505
|
+
var HEX_BASE2 = 16;
|
|
431
506
|
var noopLogger = {
|
|
432
507
|
debug: () => {
|
|
433
508
|
},
|
|
@@ -462,9 +537,17 @@ function createFFIDClient(config) {
|
|
|
462
537
|
const resolvedRedirectUri = config.redirectUri ?? null;
|
|
463
538
|
const serviceApiKey = config.serviceApiKey?.trim();
|
|
464
539
|
const verifyStrategy = config.verifyStrategy ?? "jwt";
|
|
540
|
+
const cache = config.cache;
|
|
541
|
+
const timeout = config.timeout;
|
|
465
542
|
if (authMode === "service-key" && !serviceApiKey) {
|
|
466
543
|
throw new Error("FFID Client: service-key \u30E2\u30FC\u30C9\u3067\u306F serviceApiKey \u304C\u5FC5\u9808\u3067\u3059");
|
|
467
544
|
}
|
|
545
|
+
if (cache && cache.ttl <= 0) {
|
|
546
|
+
throw new Error("FFID Client: cache.ttl \u306F\u6B63\u306E\u6570\u5024\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044");
|
|
547
|
+
}
|
|
548
|
+
if (timeout !== void 0 && timeout <= 0) {
|
|
549
|
+
throw new Error("FFID Client: timeout \u306F\u6B63\u306E\u6570\u5024\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044");
|
|
550
|
+
}
|
|
468
551
|
const logger = config.logger ?? (config.debug ? consoleLogger : noopLogger);
|
|
469
552
|
const tokenStore = authMode === "token" ? createTokenStore() : createTokenStore("memory");
|
|
470
553
|
async function fetchWithAuth(endpoint, options = {}) {
|
|
@@ -514,6 +597,7 @@ function createFFIDClient(config) {
|
|
|
514
597
|
};
|
|
515
598
|
}
|
|
516
599
|
logger.debug("Response:", response.status, raw);
|
|
600
|
+
checkVersionHeader(response, logger);
|
|
517
601
|
if (!response.ok) {
|
|
518
602
|
return {
|
|
519
603
|
error: raw.error ?? {
|
|
@@ -532,6 +616,12 @@ function createFFIDClient(config) {
|
|
|
532
616
|
}
|
|
533
617
|
return { data: raw.data };
|
|
534
618
|
}
|
|
619
|
+
function sdkHeaders() {
|
|
620
|
+
return {
|
|
621
|
+
"User-Agent": SDK_USER_AGENT,
|
|
622
|
+
[SDK_VERSION_HEADER]: SDK_VERSION
|
|
623
|
+
};
|
|
624
|
+
}
|
|
535
625
|
function buildFetchOptions(options) {
|
|
536
626
|
if (authMode === "service-key") {
|
|
537
627
|
return {
|
|
@@ -539,6 +629,7 @@ function createFFIDClient(config) {
|
|
|
539
629
|
credentials: "omit",
|
|
540
630
|
headers: {
|
|
541
631
|
"Content-Type": "application/json",
|
|
632
|
+
...sdkHeaders(),
|
|
542
633
|
"X-Service-Api-Key": serviceApiKey,
|
|
543
634
|
...options.headers
|
|
544
635
|
}
|
|
@@ -548,6 +639,7 @@ function createFFIDClient(config) {
|
|
|
548
639
|
const tokens = tokenStore.getTokens();
|
|
549
640
|
const headers = {
|
|
550
641
|
"Content-Type": "application/json",
|
|
642
|
+
...sdkHeaders(),
|
|
551
643
|
...options.headers
|
|
552
644
|
};
|
|
553
645
|
if (tokens) {
|
|
@@ -564,6 +656,7 @@ function createFFIDClient(config) {
|
|
|
564
656
|
credentials: "include",
|
|
565
657
|
headers: {
|
|
566
658
|
"Content-Type": "application/json",
|
|
659
|
+
...sdkHeaders(),
|
|
567
660
|
...options.headers
|
|
568
661
|
}
|
|
569
662
|
};
|
|
@@ -609,7 +702,8 @@ function createFFIDClient(config) {
|
|
|
609
702
|
credentials: "omit",
|
|
610
703
|
headers: {
|
|
611
704
|
"Authorization": `Bearer ${tokens.accessToken}`,
|
|
612
|
-
"Content-Type": "application/json"
|
|
705
|
+
"Content-Type": "application/json",
|
|
706
|
+
...sdkHeaders()
|
|
613
707
|
}
|
|
614
708
|
});
|
|
615
709
|
} catch (error) {
|
|
@@ -631,7 +725,8 @@ function createFFIDClient(config) {
|
|
|
631
725
|
credentials: "omit",
|
|
632
726
|
headers: {
|
|
633
727
|
"Authorization": `Bearer ${retryTokens.accessToken}`,
|
|
634
|
-
"Content-Type": "application/json"
|
|
728
|
+
"Content-Type": "application/json",
|
|
729
|
+
...sdkHeaders()
|
|
635
730
|
}
|
|
636
731
|
});
|
|
637
732
|
} catch (retryError) {
|
|
@@ -701,7 +796,7 @@ function createFFIDClient(config) {
|
|
|
701
796
|
response = await fetch(url, {
|
|
702
797
|
method: "POST",
|
|
703
798
|
credentials: "include",
|
|
704
|
-
headers: { "Content-Type": "application/json" }
|
|
799
|
+
headers: { "Content-Type": "application/json", ...sdkHeaders() }
|
|
705
800
|
});
|
|
706
801
|
} catch (error) {
|
|
707
802
|
logger.error("Network error:", error);
|
|
@@ -750,7 +845,7 @@ function createFFIDClient(config) {
|
|
|
750
845
|
await fetch(url, {
|
|
751
846
|
method: "POST",
|
|
752
847
|
credentials: "omit",
|
|
753
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
848
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...sdkHeaders() },
|
|
754
849
|
body: new URLSearchParams({
|
|
755
850
|
token: tokens.accessToken,
|
|
756
851
|
client_id: clientId
|
|
@@ -789,7 +884,7 @@ function createFFIDClient(config) {
|
|
|
789
884
|
response = await fetch(url, {
|
|
790
885
|
method: "POST",
|
|
791
886
|
credentials: "omit",
|
|
792
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
887
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...sdkHeaders() },
|
|
793
888
|
body: new URLSearchParams(body).toString()
|
|
794
889
|
});
|
|
795
890
|
} catch (error) {
|
|
@@ -847,7 +942,7 @@ function createFFIDClient(config) {
|
|
|
847
942
|
response = await fetch(url, {
|
|
848
943
|
method: "POST",
|
|
849
944
|
credentials: "omit",
|
|
850
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
945
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...sdkHeaders() },
|
|
851
946
|
body: new URLSearchParams({
|
|
852
947
|
grant_type: "refresh_token",
|
|
853
948
|
refresh_token: tokens.refreshToken,
|
|
@@ -972,7 +1067,9 @@ function createFFIDClient(config) {
|
|
|
972
1067
|
verifyStrategy,
|
|
973
1068
|
logger,
|
|
974
1069
|
createError,
|
|
975
|
-
errorCodes: FFID_ERROR_CODES
|
|
1070
|
+
errorCodes: FFID_ERROR_CODES,
|
|
1071
|
+
cache,
|
|
1072
|
+
timeout
|
|
976
1073
|
});
|
|
977
1074
|
return {
|
|
978
1075
|
getSession,
|
|
@@ -1002,7 +1099,7 @@ function createFFIDClient(config) {
|
|
|
1002
1099
|
function generateRandomState() {
|
|
1003
1100
|
const array = new Uint8Array(STATE_RANDOM_BYTES);
|
|
1004
1101
|
crypto.getRandomValues(array);
|
|
1005
|
-
return Array.from(array, (byte) => byte.toString(
|
|
1102
|
+
return Array.from(array, (byte) => byte.toString(HEX_BASE2).padStart(2, "0")).join("");
|
|
1006
1103
|
}
|
|
1007
1104
|
var DEFAULT_REFRESH_INTERVAL_MS = 5 * 60 * 1e3;
|
|
1008
1105
|
var TOKEN_REFRESH_RATIO = 0.8;
|
|
@@ -236,8 +236,11 @@ function createJwtVerifier(deps) {
|
|
|
236
236
|
|
|
237
237
|
// src/client/verify-access-token.ts
|
|
238
238
|
var OAUTH_INTROSPECT_ENDPOINT = "/api/v1/oauth/introspect";
|
|
239
|
+
var CACHE_KEY_PREFIX = "ffid:introspect:";
|
|
240
|
+
var HEX_BASE = 16;
|
|
241
|
+
var HEX_BYTE_WIDTH = 2;
|
|
239
242
|
function createVerifyAccessToken(deps) {
|
|
240
|
-
const { authMode, baseUrl, serviceCode, serviceApiKey, verifyStrategy, logger, createError, errorCodes } = deps;
|
|
243
|
+
const { authMode, baseUrl, serviceCode, serviceApiKey, verifyStrategy, logger, createError, errorCodes, cache, timeout } = deps;
|
|
241
244
|
let jwtVerify2 = null;
|
|
242
245
|
function getJwtVerifier() {
|
|
243
246
|
if (!jwtVerify2) {
|
|
@@ -284,17 +287,33 @@ function createVerifyAccessToken(deps) {
|
|
|
284
287
|
}
|
|
285
288
|
const url = `${baseUrl}${OAUTH_INTROSPECT_ENDPOINT}`;
|
|
286
289
|
logger.debug("Verifying access token:", url);
|
|
290
|
+
const cacheKey = await buildCacheKey(accessToken);
|
|
291
|
+
if (cache) {
|
|
292
|
+
try {
|
|
293
|
+
const cached = await cache.adapter.get(cacheKey);
|
|
294
|
+
if (cached && typeof cached === "object" && "sub" in cached) {
|
|
295
|
+
logger.debug("Cache hit for introspect result");
|
|
296
|
+
return { data: cached };
|
|
297
|
+
}
|
|
298
|
+
} catch (cacheError) {
|
|
299
|
+
logger.warn("Cache read failed, falling back to API call:", cacheError);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const fetchOptions = {
|
|
303
|
+
method: "POST",
|
|
304
|
+
credentials: "omit",
|
|
305
|
+
headers: {
|
|
306
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
307
|
+
"X-Service-Api-Key": serviceApiKey
|
|
308
|
+
},
|
|
309
|
+
body: new URLSearchParams({ token: accessToken }).toString()
|
|
310
|
+
};
|
|
311
|
+
if (timeout !== void 0) {
|
|
312
|
+
fetchOptions.signal = AbortSignal.timeout(timeout);
|
|
313
|
+
}
|
|
287
314
|
let response;
|
|
288
315
|
try {
|
|
289
|
-
response = await fetch(url,
|
|
290
|
-
method: "POST",
|
|
291
|
-
credentials: "omit",
|
|
292
|
-
headers: {
|
|
293
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
294
|
-
"X-Service-Api-Key": serviceApiKey
|
|
295
|
-
},
|
|
296
|
-
body: new URLSearchParams({ token: accessToken }).toString()
|
|
297
|
-
});
|
|
316
|
+
response = await fetch(url, fetchOptions);
|
|
298
317
|
} catch (error) {
|
|
299
318
|
logger.error("Network error during token verification:", error);
|
|
300
319
|
return {
|
|
@@ -360,7 +379,26 @@ function createVerifyAccessToken(deps) {
|
|
|
360
379
|
organization_id: introspectResponse.subscription.organization_id
|
|
361
380
|
}
|
|
362
381
|
} : base;
|
|
363
|
-
|
|
382
|
+
const userinfo = normalizeUserinfo(raw);
|
|
383
|
+
if (cache) {
|
|
384
|
+
try {
|
|
385
|
+
await cache.adapter.set(cacheKey, userinfo, cache.ttl);
|
|
386
|
+
} catch (cacheError) {
|
|
387
|
+
logger.warn("Cache write failed (result still returned):", cacheError);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return { data: userinfo };
|
|
391
|
+
}
|
|
392
|
+
async function buildCacheKey(token) {
|
|
393
|
+
if (typeof globalThis.crypto?.subtle?.digest === "function") {
|
|
394
|
+
const encoder = new TextEncoder();
|
|
395
|
+
const data = encoder.encode(token);
|
|
396
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
397
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
398
|
+
const hashHex = hashArray.map((b) => b.toString(HEX_BASE).padStart(HEX_BYTE_WIDTH, "0")).join("");
|
|
399
|
+
return CACHE_KEY_PREFIX + hashHex;
|
|
400
|
+
}
|
|
401
|
+
return CACHE_KEY_PREFIX + token;
|
|
364
402
|
}
|
|
365
403
|
return verifyAccessToken;
|
|
366
404
|
}
|
|
@@ -412,6 +450,43 @@ function createBillingMethods(deps) {
|
|
|
412
450
|
return { createCheckoutSession, createPortalSession };
|
|
413
451
|
}
|
|
414
452
|
|
|
453
|
+
// src/client/version-check.ts
|
|
454
|
+
var SDK_VERSION = "1.9.0";
|
|
455
|
+
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
456
|
+
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
457
|
+
var LATEST_VERSION_HEADER = "X-FFID-SDK-Latest-Version";
|
|
458
|
+
var SEMVER_PATTERN = /^\d+(\.\d+)*$/;
|
|
459
|
+
var _versionWarningShown = false;
|
|
460
|
+
function compareSemver(a, b) {
|
|
461
|
+
const cleanA = a.replace(/^v/, "");
|
|
462
|
+
const cleanB = b.replace(/^v/, "");
|
|
463
|
+
if (!SEMVER_PATTERN.test(cleanA) || !SEMVER_PATTERN.test(cleanB)) return 0;
|
|
464
|
+
const partsA = cleanA.split(".").map(Number);
|
|
465
|
+
const partsB = cleanB.split(".").map(Number);
|
|
466
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
467
|
+
for (let i = 0; i < maxLen; i++) {
|
|
468
|
+
const numA = partsA[i] ?? 0;
|
|
469
|
+
const numB = partsB[i] ?? 0;
|
|
470
|
+
if (numA < numB) return -1;
|
|
471
|
+
if (numA > numB) return 1;
|
|
472
|
+
}
|
|
473
|
+
return 0;
|
|
474
|
+
}
|
|
475
|
+
function checkVersionHeader(response, logger) {
|
|
476
|
+
if (_versionWarningShown) return;
|
|
477
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
|
|
478
|
+
if (!response.headers?.get) return;
|
|
479
|
+
const latestVersion = response.headers.get(LATEST_VERSION_HEADER);
|
|
480
|
+
if (!latestVersion) return;
|
|
481
|
+
if (compareSemver(SDK_VERSION, latestVersion) < 0) {
|
|
482
|
+
_versionWarningShown = true;
|
|
483
|
+
logger.warn(
|
|
484
|
+
`\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3\u304C\u5229\u7528\u53EF\u80FD\u3067\u3059: v${latestVersion} (\u73FE\u5728: v${SDK_VERSION})
|
|
485
|
+
npm install @feelflow/ffid-sdk@latest \u3067\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3067\u304D\u307E\u3059`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
415
490
|
// src/client/ffid-client.ts
|
|
416
491
|
var NO_CONTENT_STATUS = 204;
|
|
417
492
|
var SESSION_ENDPOINT = "/api/v1/auth/session";
|
|
@@ -425,7 +500,7 @@ var SDK_LOG_PREFIX = "[FFID SDK]";
|
|
|
425
500
|
var MS_PER_SECOND = 1e3;
|
|
426
501
|
var UNAUTHORIZED_STATUS = 401;
|
|
427
502
|
var STATE_RANDOM_BYTES = 16;
|
|
428
|
-
var
|
|
503
|
+
var HEX_BASE2 = 16;
|
|
429
504
|
var noopLogger = {
|
|
430
505
|
debug: () => {
|
|
431
506
|
},
|
|
@@ -460,9 +535,17 @@ function createFFIDClient(config) {
|
|
|
460
535
|
const resolvedRedirectUri = config.redirectUri ?? null;
|
|
461
536
|
const serviceApiKey = config.serviceApiKey?.trim();
|
|
462
537
|
const verifyStrategy = config.verifyStrategy ?? "jwt";
|
|
538
|
+
const cache = config.cache;
|
|
539
|
+
const timeout = config.timeout;
|
|
463
540
|
if (authMode === "service-key" && !serviceApiKey) {
|
|
464
541
|
throw new Error("FFID Client: service-key \u30E2\u30FC\u30C9\u3067\u306F serviceApiKey \u304C\u5FC5\u9808\u3067\u3059");
|
|
465
542
|
}
|
|
543
|
+
if (cache && cache.ttl <= 0) {
|
|
544
|
+
throw new Error("FFID Client: cache.ttl \u306F\u6B63\u306E\u6570\u5024\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044");
|
|
545
|
+
}
|
|
546
|
+
if (timeout !== void 0 && timeout <= 0) {
|
|
547
|
+
throw new Error("FFID Client: timeout \u306F\u6B63\u306E\u6570\u5024\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044");
|
|
548
|
+
}
|
|
466
549
|
const logger = config.logger ?? (config.debug ? consoleLogger : noopLogger);
|
|
467
550
|
const tokenStore = authMode === "token" ? createTokenStore() : createTokenStore("memory");
|
|
468
551
|
async function fetchWithAuth(endpoint, options = {}) {
|
|
@@ -512,6 +595,7 @@ function createFFIDClient(config) {
|
|
|
512
595
|
};
|
|
513
596
|
}
|
|
514
597
|
logger.debug("Response:", response.status, raw);
|
|
598
|
+
checkVersionHeader(response, logger);
|
|
515
599
|
if (!response.ok) {
|
|
516
600
|
return {
|
|
517
601
|
error: raw.error ?? {
|
|
@@ -530,6 +614,12 @@ function createFFIDClient(config) {
|
|
|
530
614
|
}
|
|
531
615
|
return { data: raw.data };
|
|
532
616
|
}
|
|
617
|
+
function sdkHeaders() {
|
|
618
|
+
return {
|
|
619
|
+
"User-Agent": SDK_USER_AGENT,
|
|
620
|
+
[SDK_VERSION_HEADER]: SDK_VERSION
|
|
621
|
+
};
|
|
622
|
+
}
|
|
533
623
|
function buildFetchOptions(options) {
|
|
534
624
|
if (authMode === "service-key") {
|
|
535
625
|
return {
|
|
@@ -537,6 +627,7 @@ function createFFIDClient(config) {
|
|
|
537
627
|
credentials: "omit",
|
|
538
628
|
headers: {
|
|
539
629
|
"Content-Type": "application/json",
|
|
630
|
+
...sdkHeaders(),
|
|
540
631
|
"X-Service-Api-Key": serviceApiKey,
|
|
541
632
|
...options.headers
|
|
542
633
|
}
|
|
@@ -546,6 +637,7 @@ function createFFIDClient(config) {
|
|
|
546
637
|
const tokens = tokenStore.getTokens();
|
|
547
638
|
const headers = {
|
|
548
639
|
"Content-Type": "application/json",
|
|
640
|
+
...sdkHeaders(),
|
|
549
641
|
...options.headers
|
|
550
642
|
};
|
|
551
643
|
if (tokens) {
|
|
@@ -562,6 +654,7 @@ function createFFIDClient(config) {
|
|
|
562
654
|
credentials: "include",
|
|
563
655
|
headers: {
|
|
564
656
|
"Content-Type": "application/json",
|
|
657
|
+
...sdkHeaders(),
|
|
565
658
|
...options.headers
|
|
566
659
|
}
|
|
567
660
|
};
|
|
@@ -607,7 +700,8 @@ function createFFIDClient(config) {
|
|
|
607
700
|
credentials: "omit",
|
|
608
701
|
headers: {
|
|
609
702
|
"Authorization": `Bearer ${tokens.accessToken}`,
|
|
610
|
-
"Content-Type": "application/json"
|
|
703
|
+
"Content-Type": "application/json",
|
|
704
|
+
...sdkHeaders()
|
|
611
705
|
}
|
|
612
706
|
});
|
|
613
707
|
} catch (error) {
|
|
@@ -629,7 +723,8 @@ function createFFIDClient(config) {
|
|
|
629
723
|
credentials: "omit",
|
|
630
724
|
headers: {
|
|
631
725
|
"Authorization": `Bearer ${retryTokens.accessToken}`,
|
|
632
|
-
"Content-Type": "application/json"
|
|
726
|
+
"Content-Type": "application/json",
|
|
727
|
+
...sdkHeaders()
|
|
633
728
|
}
|
|
634
729
|
});
|
|
635
730
|
} catch (retryError) {
|
|
@@ -699,7 +794,7 @@ function createFFIDClient(config) {
|
|
|
699
794
|
response = await fetch(url, {
|
|
700
795
|
method: "POST",
|
|
701
796
|
credentials: "include",
|
|
702
|
-
headers: { "Content-Type": "application/json" }
|
|
797
|
+
headers: { "Content-Type": "application/json", ...sdkHeaders() }
|
|
703
798
|
});
|
|
704
799
|
} catch (error) {
|
|
705
800
|
logger.error("Network error:", error);
|
|
@@ -748,7 +843,7 @@ function createFFIDClient(config) {
|
|
|
748
843
|
await fetch(url, {
|
|
749
844
|
method: "POST",
|
|
750
845
|
credentials: "omit",
|
|
751
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
846
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...sdkHeaders() },
|
|
752
847
|
body: new URLSearchParams({
|
|
753
848
|
token: tokens.accessToken,
|
|
754
849
|
client_id: clientId
|
|
@@ -787,7 +882,7 @@ function createFFIDClient(config) {
|
|
|
787
882
|
response = await fetch(url, {
|
|
788
883
|
method: "POST",
|
|
789
884
|
credentials: "omit",
|
|
790
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
885
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...sdkHeaders() },
|
|
791
886
|
body: new URLSearchParams(body).toString()
|
|
792
887
|
});
|
|
793
888
|
} catch (error) {
|
|
@@ -845,7 +940,7 @@ function createFFIDClient(config) {
|
|
|
845
940
|
response = await fetch(url, {
|
|
846
941
|
method: "POST",
|
|
847
942
|
credentials: "omit",
|
|
848
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
943
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", ...sdkHeaders() },
|
|
849
944
|
body: new URLSearchParams({
|
|
850
945
|
grant_type: "refresh_token",
|
|
851
946
|
refresh_token: tokens.refreshToken,
|
|
@@ -970,7 +1065,9 @@ function createFFIDClient(config) {
|
|
|
970
1065
|
verifyStrategy,
|
|
971
1066
|
logger,
|
|
972
1067
|
createError,
|
|
973
|
-
errorCodes: FFID_ERROR_CODES
|
|
1068
|
+
errorCodes: FFID_ERROR_CODES,
|
|
1069
|
+
cache,
|
|
1070
|
+
timeout
|
|
974
1071
|
});
|
|
975
1072
|
return {
|
|
976
1073
|
getSession,
|
|
@@ -1000,7 +1097,7 @@ function createFFIDClient(config) {
|
|
|
1000
1097
|
function generateRandomState() {
|
|
1001
1098
|
const array = new Uint8Array(STATE_RANDOM_BYTES);
|
|
1002
1099
|
crypto.getRandomValues(array);
|
|
1003
|
-
return Array.from(array, (byte) => byte.toString(
|
|
1100
|
+
return Array.from(array, (byte) => byte.toString(HEX_BASE2).padStart(2, "0")).join("");
|
|
1004
1101
|
}
|
|
1005
1102
|
var DEFAULT_REFRESH_INTERVAL_MS = 5 * 60 * 1e3;
|
|
1006
1103
|
var TOKEN_REFRESH_RATIO = 0.8;
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkCBYBTBKA_cjs = require('../chunk-CBYBTBKA.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "FFIDAnnouncementBadge", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDAnnouncementBadge; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "FFIDAnnouncementList", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDAnnouncementList; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "FFIDLoginButton", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDLoginButton; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDOrganizationSwitcher; }
|
|
22
22
|
});
|
|
23
23
|
Object.defineProperty(exports, "FFIDSubscriptionBadge", {
|
|
24
24
|
enumerable: true,
|
|
25
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDSubscriptionBadge; }
|
|
26
26
|
});
|
|
27
27
|
Object.defineProperty(exports, "FFIDUserMenu", {
|
|
28
28
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDUserMenu; }
|
|
30
30
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { v as FFIDAnnouncementBadge, S as FFIDAnnouncementBadgeClassNames, T as FFIDAnnouncementBadgeProps, w as FFIDAnnouncementList, V as FFIDAnnouncementListClassNames, W as FFIDAnnouncementListProps, E as FFIDLoginButton, X as FFIDLoginButtonProps, J as FFIDOrganizationSwitcher, Y as FFIDOrganizationSwitcherClassNames, Z as FFIDOrganizationSwitcherProps, M as FFIDSubscriptionBadge, _ as FFIDSubscriptionBadgeClassNames, $ as FFIDSubscriptionBadgeProps, P as FFIDUserMenu, a0 as FFIDUserMenuClassNames, a1 as FFIDUserMenuProps } from '../index-CTvhqdrH.cjs';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { v as FFIDAnnouncementBadge, S as FFIDAnnouncementBadgeClassNames, T as FFIDAnnouncementBadgeProps, w as FFIDAnnouncementList, V as FFIDAnnouncementListClassNames, W as FFIDAnnouncementListProps, E as FFIDLoginButton, X as FFIDLoginButtonProps, J as FFIDOrganizationSwitcher, Y as FFIDOrganizationSwitcherClassNames, Z as FFIDOrganizationSwitcherProps, M as FFIDSubscriptionBadge, _ as FFIDSubscriptionBadgeClassNames, $ as FFIDSubscriptionBadgeProps, P as FFIDUserMenu, a0 as FFIDUserMenuClassNames, a1 as FFIDUserMenuProps } from '../index-CTvhqdrH.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-
|
|
1
|
+
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-H5JRKOD7.js';
|
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ButtonHTMLAttributes, ReactNode, CSSProperties } from 'react';
|
|
3
3
|
|
|
4
|
+
/** Cache adapter interface for FFID SDK token verification */
|
|
5
|
+
/**
|
|
6
|
+
* Pluggable cache adapter interface.
|
|
7
|
+
* Implement this to use custom cache backends (Redis, Memcached, etc.)
|
|
8
|
+
*/
|
|
9
|
+
interface FFIDCacheAdapter {
|
|
10
|
+
/** Get a cached value by key. Returns null if not found or expired. */
|
|
11
|
+
get(key: string): Promise<unknown | null>;
|
|
12
|
+
/** Set a value with TTL in seconds. */
|
|
13
|
+
set(key: string, value: unknown, ttlSeconds: number): Promise<void>;
|
|
14
|
+
/** Delete a cached value. */
|
|
15
|
+
delete(key: string): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** Cache configuration for createFFIDClient */
|
|
18
|
+
interface FFIDCacheConfig {
|
|
19
|
+
/** Cache adapter instance */
|
|
20
|
+
adapter: FFIDCacheAdapter;
|
|
21
|
+
/** Cache TTL in seconds (how long to cache userinfo/introspect results) */
|
|
22
|
+
ttl: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
4
25
|
/**
|
|
5
26
|
* FFID SDK Type Definitions
|
|
6
27
|
*
|
|
7
28
|
* Core types for the FeelFlow ID SDK
|
|
8
29
|
*/
|
|
30
|
+
|
|
9
31
|
/**
|
|
10
32
|
* User information from FFID
|
|
11
33
|
*/
|
|
@@ -151,6 +173,18 @@ interface FFIDConfig {
|
|
|
151
173
|
* Use 'introspect' if you need full user profile data.
|
|
152
174
|
*/
|
|
153
175
|
verifyStrategy?: 'jwt' | 'introspect' | undefined;
|
|
176
|
+
/**
|
|
177
|
+
* Cache configuration for token verification results.
|
|
178
|
+
* When set, introspect/userinfo responses are cached to reduce API calls.
|
|
179
|
+
* Only effective in service-key mode with verifyStrategy: 'introspect'.
|
|
180
|
+
*/
|
|
181
|
+
cache?: FFIDCacheConfig | undefined;
|
|
182
|
+
/**
|
|
183
|
+
* Request timeout in milliseconds for FFID API calls.
|
|
184
|
+
* Applies to token verification and introspection requests.
|
|
185
|
+
* @default undefined (no timeout, uses fetch default)
|
|
186
|
+
*/
|
|
187
|
+
timeout?: number | undefined;
|
|
154
188
|
}
|
|
155
189
|
/**
|
|
156
190
|
* FFID JWT claims structure (minimal payload).
|
|
@@ -727,4 +761,4 @@ interface FFIDAnnouncementListProps {
|
|
|
727
761
|
*/
|
|
728
762
|
declare function FFIDAnnouncementList({ announcements, isLoading, className, classNames, style, formatDate, emptyMessage, loadingRender, renderItem, maxContentLines, }: FFIDAnnouncementListProps): react_jsx_runtime.JSX.Element;
|
|
729
763
|
|
|
730
|
-
export { type
|
|
764
|
+
export { type FFIDSubscriptionBadgeProps as $, type AnnouncementListResponse as A, type FFIDCacheConfig as B, type FFIDContextValue as C, type FFIDJwtClaims as D, FFIDLoginButton as E, type FFIDConfig as F, type FFIDOAuthTokenResponse as G, type FFIDOAuthUserInfoMemberRole as H, type FFIDOAuthUserInfoSubscription as I, FFIDOrganizationSwitcher as J, type FFIDSeatModel as K, type ListAnnouncementsOptions as L, FFIDSubscriptionBadge as M, type FFIDSubscriptionStatus as N, type FFIDTokenIntrospectionResponse as O, FFIDUserMenu as P, type UseFFIDAnnouncementsReturn as Q, useFFIDAnnouncements as R, type FFIDAnnouncementBadgeClassNames as S, type FFIDAnnouncementBadgeProps as T, type UseFFIDAnnouncementsOptions as U, type FFIDAnnouncementListClassNames as V, type FFIDAnnouncementListProps as W, type FFIDLoginButtonProps as X, type FFIDOrganizationSwitcherClassNames as Y, type FFIDOrganizationSwitcherProps as Z, type FFIDSubscriptionBadgeClassNames as _, type FFIDApiResponse as a, type FFIDUserMenuClassNames as a0, type FFIDUserMenuProps as a1, type FFIDSessionResponse as b, type FFIDError as c, type FFIDSubscriptionCheckResponse as d, type FFIDCreateCheckoutParams as e, type FFIDCheckoutSessionResponse as f, type FFIDCreatePortalParams as g, type FFIDPortalSessionResponse as h, type FFIDOAuthUserInfo as i, type FFIDLogger as j, type FFIDCacheAdapter as k, type FFIDUser as l, type FFIDOrganization as m, type FFIDSubscription as n, type FFIDSubscriptionContextValue as o, type FFIDAnnouncementsClientConfig as p, type FFIDAnnouncementsApiResponse as q, type FFIDAnnouncementsLogger as r, type Announcement as s, type AnnouncementStatus as t, type AnnouncementType as u, FFIDAnnouncementBadge as v, FFIDAnnouncementList as w, type FFIDAnnouncementsError as x, type FFIDAnnouncementsErrorCode as y, type FFIDAnnouncementsServerResponse as z };
|
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ButtonHTMLAttributes, ReactNode, CSSProperties } from 'react';
|
|
3
3
|
|
|
4
|
+
/** Cache adapter interface for FFID SDK token verification */
|
|
5
|
+
/**
|
|
6
|
+
* Pluggable cache adapter interface.
|
|
7
|
+
* Implement this to use custom cache backends (Redis, Memcached, etc.)
|
|
8
|
+
*/
|
|
9
|
+
interface FFIDCacheAdapter {
|
|
10
|
+
/** Get a cached value by key. Returns null if not found or expired. */
|
|
11
|
+
get(key: string): Promise<unknown | null>;
|
|
12
|
+
/** Set a value with TTL in seconds. */
|
|
13
|
+
set(key: string, value: unknown, ttlSeconds: number): Promise<void>;
|
|
14
|
+
/** Delete a cached value. */
|
|
15
|
+
delete(key: string): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** Cache configuration for createFFIDClient */
|
|
18
|
+
interface FFIDCacheConfig {
|
|
19
|
+
/** Cache adapter instance */
|
|
20
|
+
adapter: FFIDCacheAdapter;
|
|
21
|
+
/** Cache TTL in seconds (how long to cache userinfo/introspect results) */
|
|
22
|
+
ttl: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
4
25
|
/**
|
|
5
26
|
* FFID SDK Type Definitions
|
|
6
27
|
*
|
|
7
28
|
* Core types for the FeelFlow ID SDK
|
|
8
29
|
*/
|
|
30
|
+
|
|
9
31
|
/**
|
|
10
32
|
* User information from FFID
|
|
11
33
|
*/
|
|
@@ -151,6 +173,18 @@ interface FFIDConfig {
|
|
|
151
173
|
* Use 'introspect' if you need full user profile data.
|
|
152
174
|
*/
|
|
153
175
|
verifyStrategy?: 'jwt' | 'introspect' | undefined;
|
|
176
|
+
/**
|
|
177
|
+
* Cache configuration for token verification results.
|
|
178
|
+
* When set, introspect/userinfo responses are cached to reduce API calls.
|
|
179
|
+
* Only effective in service-key mode with verifyStrategy: 'introspect'.
|
|
180
|
+
*/
|
|
181
|
+
cache?: FFIDCacheConfig | undefined;
|
|
182
|
+
/**
|
|
183
|
+
* Request timeout in milliseconds for FFID API calls.
|
|
184
|
+
* Applies to token verification and introspection requests.
|
|
185
|
+
* @default undefined (no timeout, uses fetch default)
|
|
186
|
+
*/
|
|
187
|
+
timeout?: number | undefined;
|
|
154
188
|
}
|
|
155
189
|
/**
|
|
156
190
|
* FFID JWT claims structure (minimal payload).
|
|
@@ -727,4 +761,4 @@ interface FFIDAnnouncementListProps {
|
|
|
727
761
|
*/
|
|
728
762
|
declare function FFIDAnnouncementList({ announcements, isLoading, className, classNames, style, formatDate, emptyMessage, loadingRender, renderItem, maxContentLines, }: FFIDAnnouncementListProps): react_jsx_runtime.JSX.Element;
|
|
729
763
|
|
|
730
|
-
export { type
|
|
764
|
+
export { type FFIDSubscriptionBadgeProps as $, type AnnouncementListResponse as A, type FFIDCacheConfig as B, type FFIDContextValue as C, type FFIDJwtClaims as D, FFIDLoginButton as E, type FFIDConfig as F, type FFIDOAuthTokenResponse as G, type FFIDOAuthUserInfoMemberRole as H, type FFIDOAuthUserInfoSubscription as I, FFIDOrganizationSwitcher as J, type FFIDSeatModel as K, type ListAnnouncementsOptions as L, FFIDSubscriptionBadge as M, type FFIDSubscriptionStatus as N, type FFIDTokenIntrospectionResponse as O, FFIDUserMenu as P, type UseFFIDAnnouncementsReturn as Q, useFFIDAnnouncements as R, type FFIDAnnouncementBadgeClassNames as S, type FFIDAnnouncementBadgeProps as T, type UseFFIDAnnouncementsOptions as U, type FFIDAnnouncementListClassNames as V, type FFIDAnnouncementListProps as W, type FFIDLoginButtonProps as X, type FFIDOrganizationSwitcherClassNames as Y, type FFIDOrganizationSwitcherProps as Z, type FFIDSubscriptionBadgeClassNames as _, type FFIDApiResponse as a, type FFIDUserMenuClassNames as a0, type FFIDUserMenuProps as a1, type FFIDSessionResponse as b, type FFIDError as c, type FFIDSubscriptionCheckResponse as d, type FFIDCreateCheckoutParams as e, type FFIDCheckoutSessionResponse as f, type FFIDCreatePortalParams as g, type FFIDPortalSessionResponse as h, type FFIDOAuthUserInfo as i, type FFIDLogger as j, type FFIDCacheAdapter as k, type FFIDUser as l, type FFIDOrganization as m, type FFIDSubscription as n, type FFIDSubscriptionContextValue as o, type FFIDAnnouncementsClientConfig as p, type FFIDAnnouncementsApiResponse as q, type FFIDAnnouncementsLogger as r, type Announcement as s, type AnnouncementStatus as t, type AnnouncementType as u, FFIDAnnouncementBadge as v, FFIDAnnouncementList as w, type FFIDAnnouncementsError as x, type FFIDAnnouncementsErrorCode as y, type FFIDAnnouncementsServerResponse as z };
|
package/dist/index.cjs
CHANGED
|
@@ -1,12 +1,52 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkCBYBTBKA_cjs = require('./chunk-CBYBTBKA.cjs');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
|
|
7
|
+
// src/client/cache/memory-cache-adapter.ts
|
|
8
|
+
var MS_PER_SECOND = 1e3;
|
|
9
|
+
function createMemoryCacheAdapter() {
|
|
10
|
+
const store = /* @__PURE__ */ new Map();
|
|
11
|
+
return {
|
|
12
|
+
async get(key) {
|
|
13
|
+
const entry = store.get(key);
|
|
14
|
+
if (!entry) return null;
|
|
15
|
+
if (Date.now() >= entry.expiresAt) {
|
|
16
|
+
store.delete(key);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return entry.value;
|
|
20
|
+
},
|
|
21
|
+
async set(key, value, ttlSeconds) {
|
|
22
|
+
store.set(key, {
|
|
23
|
+
value,
|
|
24
|
+
expiresAt: Date.now() + ttlSeconds * MS_PER_SECOND
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
async delete(key) {
|
|
28
|
+
store.delete(key);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/client/cache/kv-cache-adapter.ts
|
|
34
|
+
function createKVCacheAdapter(kv) {
|
|
35
|
+
return {
|
|
36
|
+
async get(key) {
|
|
37
|
+
return kv.get(key, "json");
|
|
38
|
+
},
|
|
39
|
+
async set(key, value, ttlSeconds) {
|
|
40
|
+
await kv.put(key, JSON.stringify(value), { expirationTtl: ttlSeconds });
|
|
41
|
+
},
|
|
42
|
+
async delete(key) {
|
|
43
|
+
await kv.delete(key);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
7
47
|
function withFFIDAuth(Component, options = {}) {
|
|
8
48
|
const WrappedComponent = (props) => {
|
|
9
|
-
const { isLoading, isAuthenticated, login } =
|
|
49
|
+
const { isLoading, isAuthenticated, login } = chunkCBYBTBKA_cjs.useFFIDContext();
|
|
10
50
|
const hasRedirected = react.useRef(false);
|
|
11
51
|
react.useEffect(() => {
|
|
12
52
|
if (!isLoading && !isAuthenticated && options.redirectToLogin && !hasRedirected.current) {
|
|
@@ -31,82 +71,84 @@ function withFFIDAuth(Component, options = {}) {
|
|
|
31
71
|
|
|
32
72
|
Object.defineProperty(exports, "DEFAULT_API_BASE_URL", {
|
|
33
73
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
74
|
+
get: function () { return chunkCBYBTBKA_cjs.DEFAULT_API_BASE_URL; }
|
|
35
75
|
});
|
|
36
76
|
Object.defineProperty(exports, "FFIDAnnouncementBadge", {
|
|
37
77
|
enumerable: true,
|
|
38
|
-
get: function () { return
|
|
78
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDAnnouncementBadge; }
|
|
39
79
|
});
|
|
40
80
|
Object.defineProperty(exports, "FFIDAnnouncementList", {
|
|
41
81
|
enumerable: true,
|
|
42
|
-
get: function () { return
|
|
82
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDAnnouncementList; }
|
|
43
83
|
});
|
|
44
84
|
Object.defineProperty(exports, "FFIDLoginButton", {
|
|
45
85
|
enumerable: true,
|
|
46
|
-
get: function () { return
|
|
86
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDLoginButton; }
|
|
47
87
|
});
|
|
48
88
|
Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
|
|
49
89
|
enumerable: true,
|
|
50
|
-
get: function () { return
|
|
90
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDOrganizationSwitcher; }
|
|
51
91
|
});
|
|
52
92
|
Object.defineProperty(exports, "FFIDProvider", {
|
|
53
93
|
enumerable: true,
|
|
54
|
-
get: function () { return
|
|
94
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDProvider; }
|
|
55
95
|
});
|
|
56
96
|
Object.defineProperty(exports, "FFIDSubscriptionBadge", {
|
|
57
97
|
enumerable: true,
|
|
58
|
-
get: function () { return
|
|
98
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDSubscriptionBadge; }
|
|
59
99
|
});
|
|
60
100
|
Object.defineProperty(exports, "FFIDUserMenu", {
|
|
61
101
|
enumerable: true,
|
|
62
|
-
get: function () { return
|
|
102
|
+
get: function () { return chunkCBYBTBKA_cjs.FFIDUserMenu; }
|
|
63
103
|
});
|
|
64
104
|
Object.defineProperty(exports, "FFID_ANNOUNCEMENTS_ERROR_CODES", {
|
|
65
105
|
enumerable: true,
|
|
66
|
-
get: function () { return
|
|
106
|
+
get: function () { return chunkCBYBTBKA_cjs.FFID_ANNOUNCEMENTS_ERROR_CODES; }
|
|
67
107
|
});
|
|
68
108
|
Object.defineProperty(exports, "createFFIDAnnouncementsClient", {
|
|
69
109
|
enumerable: true,
|
|
70
|
-
get: function () { return
|
|
110
|
+
get: function () { return chunkCBYBTBKA_cjs.createFFIDAnnouncementsClient; }
|
|
71
111
|
});
|
|
72
112
|
Object.defineProperty(exports, "createFFIDClient", {
|
|
73
113
|
enumerable: true,
|
|
74
|
-
get: function () { return
|
|
114
|
+
get: function () { return chunkCBYBTBKA_cjs.createFFIDClient; }
|
|
75
115
|
});
|
|
76
116
|
Object.defineProperty(exports, "createTokenStore", {
|
|
77
117
|
enumerable: true,
|
|
78
|
-
get: function () { return
|
|
118
|
+
get: function () { return chunkCBYBTBKA_cjs.createTokenStore; }
|
|
79
119
|
});
|
|
80
120
|
Object.defineProperty(exports, "generateCodeChallenge", {
|
|
81
121
|
enumerable: true,
|
|
82
|
-
get: function () { return
|
|
122
|
+
get: function () { return chunkCBYBTBKA_cjs.generateCodeChallenge; }
|
|
83
123
|
});
|
|
84
124
|
Object.defineProperty(exports, "generateCodeVerifier", {
|
|
85
125
|
enumerable: true,
|
|
86
|
-
get: function () { return
|
|
126
|
+
get: function () { return chunkCBYBTBKA_cjs.generateCodeVerifier; }
|
|
87
127
|
});
|
|
88
128
|
Object.defineProperty(exports, "retrieveCodeVerifier", {
|
|
89
129
|
enumerable: true,
|
|
90
|
-
get: function () { return
|
|
130
|
+
get: function () { return chunkCBYBTBKA_cjs.retrieveCodeVerifier; }
|
|
91
131
|
});
|
|
92
132
|
Object.defineProperty(exports, "storeCodeVerifier", {
|
|
93
133
|
enumerable: true,
|
|
94
|
-
get: function () { return
|
|
134
|
+
get: function () { return chunkCBYBTBKA_cjs.storeCodeVerifier; }
|
|
95
135
|
});
|
|
96
136
|
Object.defineProperty(exports, "useFFID", {
|
|
97
137
|
enumerable: true,
|
|
98
|
-
get: function () { return
|
|
138
|
+
get: function () { return chunkCBYBTBKA_cjs.useFFID; }
|
|
99
139
|
});
|
|
100
140
|
Object.defineProperty(exports, "useFFIDAnnouncements", {
|
|
101
141
|
enumerable: true,
|
|
102
|
-
get: function () { return
|
|
142
|
+
get: function () { return chunkCBYBTBKA_cjs.useFFIDAnnouncements; }
|
|
103
143
|
});
|
|
104
144
|
Object.defineProperty(exports, "useSubscription", {
|
|
105
145
|
enumerable: true,
|
|
106
|
-
get: function () { return
|
|
146
|
+
get: function () { return chunkCBYBTBKA_cjs.useSubscription; }
|
|
107
147
|
});
|
|
108
148
|
Object.defineProperty(exports, "withSubscription", {
|
|
109
149
|
enumerable: true,
|
|
110
|
-
get: function () { return
|
|
150
|
+
get: function () { return chunkCBYBTBKA_cjs.withSubscription; }
|
|
111
151
|
});
|
|
152
|
+
exports.createKVCacheAdapter = createKVCacheAdapter;
|
|
153
|
+
exports.createMemoryCacheAdapter = createMemoryCacheAdapter;
|
|
112
154
|
exports.withFFIDAuth = withFFIDAuth;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FFIDConfig, a as FFIDApiResponse, b as FFIDSessionResponse, c as FFIDError, d as FFIDSubscriptionCheckResponse, e as FFIDCreateCheckoutParams, f as FFIDCheckoutSessionResponse, g as FFIDCreatePortalParams, h as FFIDPortalSessionResponse, i as FFIDOAuthUserInfo, j as FFIDLogger, k as
|
|
2
|
-
export {
|
|
1
|
+
import { F as FFIDConfig, a as FFIDApiResponse, b as FFIDSessionResponse, c as FFIDError, d as FFIDSubscriptionCheckResponse, e as FFIDCreateCheckoutParams, f as FFIDCheckoutSessionResponse, g as FFIDCreatePortalParams, h as FFIDPortalSessionResponse, i as FFIDOAuthUserInfo, j as FFIDLogger, k as FFIDCacheAdapter, l as FFIDUser, m as FFIDOrganization, n as FFIDSubscription, o as FFIDSubscriptionContextValue, p as FFIDAnnouncementsClientConfig, L as ListAnnouncementsOptions, q as FFIDAnnouncementsApiResponse, A as AnnouncementListResponse, r as FFIDAnnouncementsLogger } from './index-CTvhqdrH.cjs';
|
|
2
|
+
export { s as Announcement, t as AnnouncementStatus, u as AnnouncementType, v as FFIDAnnouncementBadge, w as FFIDAnnouncementList, x as FFIDAnnouncementsError, y as FFIDAnnouncementsErrorCode, z as FFIDAnnouncementsServerResponse, B as FFIDCacheConfig, C as FFIDContextValue, D as FFIDJwtClaims, E as FFIDLoginButton, G as FFIDOAuthTokenResponse, H as FFIDOAuthUserInfoMemberRole, I as FFIDOAuthUserInfoSubscription, J as FFIDOrganizationSwitcher, K as FFIDSeatModel, M as FFIDSubscriptionBadge, N as FFIDSubscriptionStatus, O as FFIDTokenIntrospectionResponse, P as FFIDUserMenu, U as UseFFIDAnnouncementsOptions, Q as UseFFIDAnnouncementsReturn, R as useFFIDAnnouncements } from './index-CTvhqdrH.cjs';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import { ReactNode, ComponentType, FC } from 'react';
|
|
5
5
|
|
|
@@ -115,6 +115,29 @@ declare function createFFIDClient(config: FFIDConfig): {
|
|
|
115
115
|
/** Type of the FFID client */
|
|
116
116
|
type FFIDClient = ReturnType<typeof createFFIDClient>;
|
|
117
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Create an in-memory cache adapter using a Map.
|
|
120
|
+
* Suitable for single-process environments (e.g., development, testing).
|
|
121
|
+
*/
|
|
122
|
+
declare function createMemoryCacheAdapter(): FFIDCacheAdapter;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Minimal KVNamespace-compatible interface.
|
|
126
|
+
* Matches Cloudflare Workers KV without requiring the CF Workers dependency.
|
|
127
|
+
*/
|
|
128
|
+
interface KVNamespaceLike {
|
|
129
|
+
get(key: string, type: 'json'): Promise<unknown | null>;
|
|
130
|
+
put(key: string, value: string, options?: {
|
|
131
|
+
expirationTtl?: number;
|
|
132
|
+
}): Promise<void>;
|
|
133
|
+
delete(key: string): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create a cache adapter backed by a KVNamespace-compatible store.
|
|
137
|
+
* Suitable for Cloudflare Workers and other KV-based environments.
|
|
138
|
+
*/
|
|
139
|
+
declare function createKVCacheAdapter(kv: KVNamespaceLike): FFIDCacheAdapter;
|
|
140
|
+
|
|
118
141
|
/**
|
|
119
142
|
* Props for FFIDProvider component
|
|
120
143
|
*/
|
|
@@ -343,4 +366,4 @@ declare function createFFIDAnnouncementsClient(config?: FFIDAnnouncementsClientC
|
|
|
343
366
|
/** Type of the FFID Announcements client */
|
|
344
367
|
type FFIDAnnouncementsClient = ReturnType<typeof createFFIDAnnouncementsClient>;
|
|
345
368
|
|
|
346
|
-
export { AnnouncementListResponse, DEFAULT_API_BASE_URL, FFIDAnnouncementsApiResponse, type FFIDAnnouncementsClient, FFIDAnnouncementsClientConfig, FFIDAnnouncementsLogger, FFIDApiResponse, FFIDCheckoutSessionResponse, type FFIDClient, FFIDConfig, FFIDCreateCheckoutParams, FFIDCreatePortalParams, FFIDError, FFIDLogger, FFIDOAuthUserInfo, FFIDOrganization, FFIDPortalSessionResponse, FFIDProvider, type FFIDProviderProps, FFIDSessionResponse, FFIDSubscription, FFIDSubscriptionCheckResponse, FFIDSubscriptionContextValue, FFIDUser, FFID_ANNOUNCEMENTS_ERROR_CODES, ListAnnouncementsOptions, type TokenData, type TokenStore, type UseFFIDReturn, type WithFFIDAuthOptions, type WithSubscriptionOptions, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, retrieveCodeVerifier, storeCodeVerifier, useFFID, useSubscription, withFFIDAuth, withSubscription };
|
|
369
|
+
export { AnnouncementListResponse, DEFAULT_API_BASE_URL, FFIDAnnouncementsApiResponse, type FFIDAnnouncementsClient, FFIDAnnouncementsClientConfig, FFIDAnnouncementsLogger, FFIDApiResponse, FFIDCacheAdapter, FFIDCheckoutSessionResponse, type FFIDClient, FFIDConfig, FFIDCreateCheckoutParams, FFIDCreatePortalParams, FFIDError, FFIDLogger, FFIDOAuthUserInfo, FFIDOrganization, FFIDPortalSessionResponse, FFIDProvider, type FFIDProviderProps, FFIDSessionResponse, FFIDSubscription, FFIDSubscriptionCheckResponse, FFIDSubscriptionContextValue, FFIDUser, FFID_ANNOUNCEMENTS_ERROR_CODES, type KVNamespaceLike, ListAnnouncementsOptions, type TokenData, type TokenStore, type UseFFIDReturn, type WithFFIDAuthOptions, type WithSubscriptionOptions, createFFIDAnnouncementsClient, createFFIDClient, createKVCacheAdapter, createMemoryCacheAdapter, createTokenStore, generateCodeChallenge, generateCodeVerifier, retrieveCodeVerifier, storeCodeVerifier, useFFID, useSubscription, withFFIDAuth, withSubscription };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FFIDConfig, a as FFIDApiResponse, b as FFIDSessionResponse, c as FFIDError, d as FFIDSubscriptionCheckResponse, e as FFIDCreateCheckoutParams, f as FFIDCheckoutSessionResponse, g as FFIDCreatePortalParams, h as FFIDPortalSessionResponse, i as FFIDOAuthUserInfo, j as FFIDLogger, k as
|
|
2
|
-
export {
|
|
1
|
+
import { F as FFIDConfig, a as FFIDApiResponse, b as FFIDSessionResponse, c as FFIDError, d as FFIDSubscriptionCheckResponse, e as FFIDCreateCheckoutParams, f as FFIDCheckoutSessionResponse, g as FFIDCreatePortalParams, h as FFIDPortalSessionResponse, i as FFIDOAuthUserInfo, j as FFIDLogger, k as FFIDCacheAdapter, l as FFIDUser, m as FFIDOrganization, n as FFIDSubscription, o as FFIDSubscriptionContextValue, p as FFIDAnnouncementsClientConfig, L as ListAnnouncementsOptions, q as FFIDAnnouncementsApiResponse, A as AnnouncementListResponse, r as FFIDAnnouncementsLogger } from './index-CTvhqdrH.js';
|
|
2
|
+
export { s as Announcement, t as AnnouncementStatus, u as AnnouncementType, v as FFIDAnnouncementBadge, w as FFIDAnnouncementList, x as FFIDAnnouncementsError, y as FFIDAnnouncementsErrorCode, z as FFIDAnnouncementsServerResponse, B as FFIDCacheConfig, C as FFIDContextValue, D as FFIDJwtClaims, E as FFIDLoginButton, G as FFIDOAuthTokenResponse, H as FFIDOAuthUserInfoMemberRole, I as FFIDOAuthUserInfoSubscription, J as FFIDOrganizationSwitcher, K as FFIDSeatModel, M as FFIDSubscriptionBadge, N as FFIDSubscriptionStatus, O as FFIDTokenIntrospectionResponse, P as FFIDUserMenu, U as UseFFIDAnnouncementsOptions, Q as UseFFIDAnnouncementsReturn, R as useFFIDAnnouncements } from './index-CTvhqdrH.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import { ReactNode, ComponentType, FC } from 'react';
|
|
5
5
|
|
|
@@ -115,6 +115,29 @@ declare function createFFIDClient(config: FFIDConfig): {
|
|
|
115
115
|
/** Type of the FFID client */
|
|
116
116
|
type FFIDClient = ReturnType<typeof createFFIDClient>;
|
|
117
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Create an in-memory cache adapter using a Map.
|
|
120
|
+
* Suitable for single-process environments (e.g., development, testing).
|
|
121
|
+
*/
|
|
122
|
+
declare function createMemoryCacheAdapter(): FFIDCacheAdapter;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Minimal KVNamespace-compatible interface.
|
|
126
|
+
* Matches Cloudflare Workers KV without requiring the CF Workers dependency.
|
|
127
|
+
*/
|
|
128
|
+
interface KVNamespaceLike {
|
|
129
|
+
get(key: string, type: 'json'): Promise<unknown | null>;
|
|
130
|
+
put(key: string, value: string, options?: {
|
|
131
|
+
expirationTtl?: number;
|
|
132
|
+
}): Promise<void>;
|
|
133
|
+
delete(key: string): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create a cache adapter backed by a KVNamespace-compatible store.
|
|
137
|
+
* Suitable for Cloudflare Workers and other KV-based environments.
|
|
138
|
+
*/
|
|
139
|
+
declare function createKVCacheAdapter(kv: KVNamespaceLike): FFIDCacheAdapter;
|
|
140
|
+
|
|
118
141
|
/**
|
|
119
142
|
* Props for FFIDProvider component
|
|
120
143
|
*/
|
|
@@ -343,4 +366,4 @@ declare function createFFIDAnnouncementsClient(config?: FFIDAnnouncementsClientC
|
|
|
343
366
|
/** Type of the FFID Announcements client */
|
|
344
367
|
type FFIDAnnouncementsClient = ReturnType<typeof createFFIDAnnouncementsClient>;
|
|
345
368
|
|
|
346
|
-
export { AnnouncementListResponse, DEFAULT_API_BASE_URL, FFIDAnnouncementsApiResponse, type FFIDAnnouncementsClient, FFIDAnnouncementsClientConfig, FFIDAnnouncementsLogger, FFIDApiResponse, FFIDCheckoutSessionResponse, type FFIDClient, FFIDConfig, FFIDCreateCheckoutParams, FFIDCreatePortalParams, FFIDError, FFIDLogger, FFIDOAuthUserInfo, FFIDOrganization, FFIDPortalSessionResponse, FFIDProvider, type FFIDProviderProps, FFIDSessionResponse, FFIDSubscription, FFIDSubscriptionCheckResponse, FFIDSubscriptionContextValue, FFIDUser, FFID_ANNOUNCEMENTS_ERROR_CODES, ListAnnouncementsOptions, type TokenData, type TokenStore, type UseFFIDReturn, type WithFFIDAuthOptions, type WithSubscriptionOptions, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, retrieveCodeVerifier, storeCodeVerifier, useFFID, useSubscription, withFFIDAuth, withSubscription };
|
|
369
|
+
export { AnnouncementListResponse, DEFAULT_API_BASE_URL, FFIDAnnouncementsApiResponse, type FFIDAnnouncementsClient, FFIDAnnouncementsClientConfig, FFIDAnnouncementsLogger, FFIDApiResponse, FFIDCacheAdapter, FFIDCheckoutSessionResponse, type FFIDClient, FFIDConfig, FFIDCreateCheckoutParams, FFIDCreatePortalParams, FFIDError, FFIDLogger, FFIDOAuthUserInfo, FFIDOrganization, FFIDPortalSessionResponse, FFIDProvider, type FFIDProviderProps, FFIDSessionResponse, FFIDSubscription, FFIDSubscriptionCheckResponse, FFIDSubscriptionContextValue, FFIDUser, FFID_ANNOUNCEMENTS_ERROR_CODES, type KVNamespaceLike, ListAnnouncementsOptions, type TokenData, type TokenStore, type UseFFIDReturn, type WithFFIDAuthOptions, type WithSubscriptionOptions, createFFIDAnnouncementsClient, createFFIDClient, createKVCacheAdapter, createMemoryCacheAdapter, createTokenStore, generateCodeChallenge, generateCodeVerifier, retrieveCodeVerifier, storeCodeVerifier, useFFID, useSubscription, withFFIDAuth, withSubscription };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,48 @@
|
|
|
1
|
-
import { useFFIDContext } from './chunk-
|
|
2
|
-
export { DEFAULT_API_BASE_URL, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ANNOUNCEMENTS_ERROR_CODES, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, retrieveCodeVerifier, storeCodeVerifier, useFFID, useFFIDAnnouncements, useSubscription, withSubscription } from './chunk-
|
|
1
|
+
import { useFFIDContext } from './chunk-H5JRKOD7.js';
|
|
2
|
+
export { DEFAULT_API_BASE_URL, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ANNOUNCEMENTS_ERROR_CODES, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, retrieveCodeVerifier, storeCodeVerifier, useFFID, useFFIDAnnouncements, useSubscription, withSubscription } from './chunk-H5JRKOD7.js';
|
|
3
3
|
import { useRef, useEffect } from 'react';
|
|
4
4
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
+
// src/client/cache/memory-cache-adapter.ts
|
|
7
|
+
var MS_PER_SECOND = 1e3;
|
|
8
|
+
function createMemoryCacheAdapter() {
|
|
9
|
+
const store = /* @__PURE__ */ new Map();
|
|
10
|
+
return {
|
|
11
|
+
async get(key) {
|
|
12
|
+
const entry = store.get(key);
|
|
13
|
+
if (!entry) return null;
|
|
14
|
+
if (Date.now() >= entry.expiresAt) {
|
|
15
|
+
store.delete(key);
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return entry.value;
|
|
19
|
+
},
|
|
20
|
+
async set(key, value, ttlSeconds) {
|
|
21
|
+
store.set(key, {
|
|
22
|
+
value,
|
|
23
|
+
expiresAt: Date.now() + ttlSeconds * MS_PER_SECOND
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
async delete(key) {
|
|
27
|
+
store.delete(key);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/client/cache/kv-cache-adapter.ts
|
|
33
|
+
function createKVCacheAdapter(kv) {
|
|
34
|
+
return {
|
|
35
|
+
async get(key) {
|
|
36
|
+
return kv.get(key, "json");
|
|
37
|
+
},
|
|
38
|
+
async set(key, value, ttlSeconds) {
|
|
39
|
+
await kv.put(key, JSON.stringify(value), { expirationTtl: ttlSeconds });
|
|
40
|
+
},
|
|
41
|
+
async delete(key) {
|
|
42
|
+
await kv.delete(key);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
6
46
|
function withFFIDAuth(Component, options = {}) {
|
|
7
47
|
const WrappedComponent = (props) => {
|
|
8
48
|
const { isLoading, isAuthenticated, login } = useFFIDContext();
|
|
@@ -28,4 +68,4 @@ function withFFIDAuth(Component, options = {}) {
|
|
|
28
68
|
return WrappedComponent;
|
|
29
69
|
}
|
|
30
70
|
|
|
31
|
-
export { withFFIDAuth };
|
|
71
|
+
export { createKVCacheAdapter, createMemoryCacheAdapter, withFFIDAuth };
|