@vercel/flags-core 1.10.1 → 1.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/{chunk-CAVQRHGX.js → chunk-2P2UTT7O.js} +65 -23
- package/dist/chunk-2P2UTT7O.js.map +1 -0
- package/dist/{chunk-EW4YJU7V.cjs → chunk-BEQ3MX7Z.cjs} +76 -34
- package/dist/chunk-BEQ3MX7Z.cjs.map +1 -0
- package/dist/{chunk-R3QYUMRA.cjs → chunk-EGGUENXP.cjs} +77 -35
- package/dist/chunk-EGGUENXP.cjs.map +1 -0
- package/dist/{chunk-ZY7CHPJG.js → chunk-OIOT7N7A.js} +65 -23
- package/dist/chunk-OIOT7N7A.js.map +1 -0
- package/dist/index.default.cjs +2 -2
- package/dist/index.default.d.cts +5 -2
- package/dist/index.default.d.ts +5 -2
- package/dist/index.default.js +1 -1
- package/dist/index.next-js.cjs +2 -2
- package/dist/index.next-js.d.cts +5 -2
- package/dist/index.next-js.d.ts +5 -2
- package/dist/index.next-js.js +1 -1
- package/dist/openfeature.default.cjs +2 -2
- package/dist/openfeature.default.js +1 -1
- package/dist/openfeature.next-js.cjs +2 -2
- package/dist/openfeature.next-js.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-CAVQRHGX.js.map +0 -1
- package/dist/chunk-EW4YJU7V.cjs.map +0 -1
- package/dist/chunk-R3QYUMRA.cjs.map +0 -1
- package/dist/chunk-ZY7CHPJG.js.map +0 -1
|
@@ -559,7 +559,7 @@ function bulkEvaluate(flags, shared) {
|
|
|
559
559
|
}
|
|
560
560
|
|
|
561
561
|
// package.json
|
|
562
|
-
var version = "1.10.
|
|
562
|
+
var version = "1.10.3";
|
|
563
563
|
|
|
564
564
|
// src/lib/report-value.ts
|
|
565
565
|
function internalReportValue(key, value, data) {
|
|
@@ -1087,19 +1087,28 @@ function unauthorizedMessage(sourceProjectId) {
|
|
|
1087
1087
|
if (!sourceProjectId) {
|
|
1088
1088
|
return "unauthorized (401)";
|
|
1089
1089
|
}
|
|
1090
|
-
return `unauthorized (401): this deployment is not allowed to read the flags of project "${sourceProjectId}". Check that the project is connected
|
|
1090
|
+
return `unauthorized (401): this deployment is not allowed to read the flags of project "${sourceProjectId}". Check that the project is connected. See https://vercel.com/docs/flags/vercel-flags/project-connections`;
|
|
1091
1091
|
}
|
|
1092
|
+
var oidcTokenMessage = [
|
|
1093
|
+
"@vercel/flags-core: Failed to get OIDC token.",
|
|
1094
|
+
"Are you running in a Vercel Environment where OIDC tokens are available?",
|
|
1095
|
+
"Did you mean to use an SDK Key instead? Use the environment variable FLAGS or pass it directly to the client."
|
|
1096
|
+
].join(" ");
|
|
1097
|
+
var missingCredentials = /`vc link|vercel login|^The 'x-vercel-oidc-token' header is missing from the request\.$/;
|
|
1098
|
+
var OidcTokenError = class extends Error {
|
|
1099
|
+
constructor(cause) {
|
|
1100
|
+
super(oidcTokenMessage, { cause });
|
|
1101
|
+
this.name = "OidcTokenError";
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1092
1104
|
async function getOidcToken() {
|
|
1093
1105
|
try {
|
|
1094
1106
|
return await getVercelOidcToken();
|
|
1095
|
-
} catch {
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
"Did you mean to use an SDK Key instead? Use the environment variable FLAGS or pass it directly to the client."
|
|
1101
|
-
].join(" ")
|
|
1102
|
-
);
|
|
1107
|
+
} catch (error) {
|
|
1108
|
+
if (error instanceof Error && missingCredentials.test(error.message)) {
|
|
1109
|
+
throw new OidcTokenError(error);
|
|
1110
|
+
}
|
|
1111
|
+
throw new Error(oidcTokenMessage, { cause: error });
|
|
1103
1112
|
}
|
|
1104
1113
|
}
|
|
1105
1114
|
function getProjectIdFromOidcToken(oidcToken) {
|
|
@@ -1142,13 +1151,24 @@ var Authentication = class {
|
|
|
1142
1151
|
}
|
|
1143
1152
|
return await getOidcToken();
|
|
1144
1153
|
}
|
|
1145
|
-
|
|
1154
|
+
getStaticBundledDefinitionsLookup() {
|
|
1146
1155
|
if (this.sdkKey) {
|
|
1147
1156
|
return { type: "sdk-key", sdkKey: this.sdkKey };
|
|
1148
1157
|
}
|
|
1149
1158
|
if (this.sourceProjectId) {
|
|
1150
1159
|
return { type: "project-id", projectId: this.sourceProjectId };
|
|
1151
1160
|
}
|
|
1161
|
+
const projectId = process.env.VERCEL_PROJECT_ID;
|
|
1162
|
+
if (projectId) {
|
|
1163
|
+
return { type: "project-id", projectId };
|
|
1164
|
+
}
|
|
1165
|
+
return void 0;
|
|
1166
|
+
}
|
|
1167
|
+
async resolveBundledDefinitionsLookup() {
|
|
1168
|
+
const lookup = this.getStaticBundledDefinitionsLookup();
|
|
1169
|
+
if (lookup) {
|
|
1170
|
+
return lookup;
|
|
1171
|
+
}
|
|
1152
1172
|
const oidcToken = await this.resolveToken();
|
|
1153
1173
|
return {
|
|
1154
1174
|
type: "project-id",
|
|
@@ -1658,6 +1678,13 @@ var BundledSource = class {
|
|
|
1658
1678
|
}
|
|
1659
1679
|
return void 0;
|
|
1660
1680
|
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Starts reading bundled definitions without waiting for the result.
|
|
1683
|
+
*/
|
|
1684
|
+
preload() {
|
|
1685
|
+
this.getResult().catch(() => {
|
|
1686
|
+
});
|
|
1687
|
+
}
|
|
1661
1688
|
getResult() {
|
|
1662
1689
|
if (!this.promise) {
|
|
1663
1690
|
this.promise = this.options.readBundledDefinitions(this.options.auth);
|
|
@@ -2125,7 +2152,8 @@ async function fetchDatafile(options) {
|
|
|
2125
2152
|
return await Promise.race([fetchAttempt(attempt + 1), aborted]);
|
|
2126
2153
|
} catch (error) {
|
|
2127
2154
|
signal.throwIfAborted();
|
|
2128
|
-
if (attempt === maxAttempts - 1 || error instanceof DatafileHttpError && !error.retryable
|
|
2155
|
+
if (attempt === maxAttempts - 1 || error instanceof DatafileHttpError && !error.retryable || // Retrying will not produce a token that is not there.
|
|
2156
|
+
error instanceof OidcTokenError) {
|
|
2129
2157
|
throw error instanceof Error ? error : new Error("Unknown fetch error");
|
|
2130
2158
|
}
|
|
2131
2159
|
debug(options.clientName, "datafile.fetch.retry", () => ({
|
|
@@ -2543,7 +2571,7 @@ async function connectStream(config, callbacks) {
|
|
|
2543
2571
|
rejectInit(error);
|
|
2544
2572
|
}
|
|
2545
2573
|
onDisconnect?.();
|
|
2546
|
-
abortController.abort();
|
|
2574
|
+
abortController.abort(error);
|
|
2547
2575
|
break;
|
|
2548
2576
|
}
|
|
2549
2577
|
if (!response.ok) {
|
|
@@ -2645,7 +2673,7 @@ async function connectStream(config, callbacks) {
|
|
|
2645
2673
|
}
|
|
2646
2674
|
if (error instanceof TokenResolutionError && !initialDataReceived) {
|
|
2647
2675
|
rejectInit(error.cause);
|
|
2648
|
-
abortController.abort();
|
|
2676
|
+
abortController.abort(error.cause);
|
|
2649
2677
|
break;
|
|
2650
2678
|
}
|
|
2651
2679
|
if (connectionAbort.signal.reason !== PING_TIMEOUT) {
|
|
@@ -2719,7 +2747,7 @@ var StreamSource = class extends TypedEmitter {
|
|
|
2719
2747
|
if (this.abortController === abortController) {
|
|
2720
2748
|
this.promise = void 0;
|
|
2721
2749
|
this.abortController = void 0;
|
|
2722
|
-
this.emit("exhausted");
|
|
2750
|
+
this.emit("exhausted", abortController.signal.reason);
|
|
2723
2751
|
}
|
|
2724
2752
|
},
|
|
2725
2753
|
{ once: true }
|
|
@@ -2780,7 +2808,7 @@ var UNKNOWN_FRESHNESS = {
|
|
|
2780
2808
|
assess: () => ({ status: "unknown" })
|
|
2781
2809
|
};
|
|
2782
2810
|
function isUnauthorizedError(error) {
|
|
2783
|
-
if (error instanceof UnauthorizedError) {
|
|
2811
|
+
if (error instanceof UnauthorizedError || error instanceof OidcTokenError) {
|
|
2784
2812
|
return true;
|
|
2785
2813
|
}
|
|
2786
2814
|
if (!(error instanceof Error)) {
|
|
@@ -2815,8 +2843,9 @@ var Controller = class {
|
|
|
2815
2843
|
// Build-step deduplication
|
|
2816
2844
|
buildDataPromise = null;
|
|
2817
2845
|
buildReadTracked = false;
|
|
2818
|
-
// Suppresses usage tracking while the credential is rejected
|
|
2819
|
-
//
|
|
2846
|
+
// Suppresses usage tracking while the credential is rejected or no OIDC
|
|
2847
|
+
// token is available. Set on an auth failure from any source, cleared as
|
|
2848
|
+
// soon as a source delivers data again.
|
|
2820
2849
|
unauthorized = false;
|
|
2821
2850
|
constructor(options) {
|
|
2822
2851
|
this.options = normalizeOptions(options);
|
|
@@ -2853,6 +2882,9 @@ var Controller = class {
|
|
|
2853
2882
|
auth: this.options.auth,
|
|
2854
2883
|
readBundledDefinitions
|
|
2855
2884
|
});
|
|
2885
|
+
if (!this.options.datafile && this.options.auth.getStaticBundledDefinitionsLookup()) {
|
|
2886
|
+
this.bundledSource.preload();
|
|
2887
|
+
}
|
|
2856
2888
|
this.wireSourceEvents();
|
|
2857
2889
|
if (this.options.datafile) {
|
|
2858
2890
|
this.cache.seed(tagData({ ...this.options.datafile }, "provided"));
|
|
@@ -2909,10 +2941,16 @@ var Controller = class {
|
|
|
2909
2941
|
this.transition("degraded", "stream-disconnected");
|
|
2910
2942
|
}
|
|
2911
2943
|
};
|
|
2912
|
-
onStreamExhausted = () => {
|
|
2944
|
+
onStreamExhausted = (reason) => {
|
|
2913
2945
|
if (this.state !== "streaming" && this.state !== "degraded") {
|
|
2914
2946
|
return;
|
|
2915
2947
|
}
|
|
2948
|
+
if (isUnauthorizedError(reason)) {
|
|
2949
|
+
if (this.state === "streaming") {
|
|
2950
|
+
this.transition("degraded", "stream-auth-failed");
|
|
2951
|
+
}
|
|
2952
|
+
return;
|
|
2953
|
+
}
|
|
2916
2954
|
void this.activateFallbackSource().catch(() => {
|
|
2917
2955
|
});
|
|
2918
2956
|
};
|
|
@@ -2924,7 +2962,7 @@ var Controller = class {
|
|
|
2924
2962
|
this.onSourceError(error);
|
|
2925
2963
|
if (this.state === "polling" && isUnauthorizedError(error)) {
|
|
2926
2964
|
this.pollingSource.stop();
|
|
2927
|
-
this.transition("degraded", "polling-
|
|
2965
|
+
this.transition("degraded", "polling-auth-failed");
|
|
2928
2966
|
}
|
|
2929
2967
|
};
|
|
2930
2968
|
// ---------------------------------------------------------------------------
|
|
@@ -3334,6 +3372,10 @@ var Controller = class {
|
|
|
3334
3372
|
this.transition("degraded", "stream-still-connecting");
|
|
3335
3373
|
return;
|
|
3336
3374
|
}
|
|
3375
|
+
if (outcome === "auth-failed") {
|
|
3376
|
+
this.transition("degraded", "stream-auth-failed");
|
|
3377
|
+
return;
|
|
3378
|
+
}
|
|
3337
3379
|
}
|
|
3338
3380
|
if (this.options.polling.enabled) {
|
|
3339
3381
|
if (this.state !== "polling") {
|
|
@@ -3366,7 +3408,7 @@ var Controller = class {
|
|
|
3366
3408
|
return "connected";
|
|
3367
3409
|
} catch (error) {
|
|
3368
3410
|
this.noteUnauthorized(error);
|
|
3369
|
-
return "failed";
|
|
3411
|
+
return isUnauthorizedError(error) ? "auth-failed" : "failed";
|
|
3370
3412
|
}
|
|
3371
3413
|
}
|
|
3372
3414
|
let timeoutId;
|
|
@@ -3400,7 +3442,7 @@ var Controller = class {
|
|
|
3400
3442
|
} catch (error) {
|
|
3401
3443
|
clearTimeout(timeoutId);
|
|
3402
3444
|
this.noteUnauthorized(error);
|
|
3403
|
-
return "failed";
|
|
3445
|
+
return isUnauthorizedError(error) ? "auth-failed" : "failed";
|
|
3404
3446
|
}
|
|
3405
3447
|
}
|
|
3406
3448
|
// ---------------------------------------------------------------------------
|
|
@@ -3754,4 +3796,4 @@ export {
|
|
|
3754
3796
|
resetDefaultFlagsClient,
|
|
3755
3797
|
createClient
|
|
3756
3798
|
};
|
|
3757
|
-
//# sourceMappingURL=chunk-
|
|
3799
|
+
//# sourceMappingURL=chunk-OIOT7N7A.js.map
|