UNPKG

@vercel/flags

Version:

Flags SDK by Vercel - The feature flags toolkit for Next.js and SvelteKit

173 lines (158 loc) 6.17 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _chunkAVMIIWOFcjs = require('./chunk-AVMIIWOF.cjs'); var _chunkJYRFFBKMcjs = require('./chunk-JYRFFBKM.cjs'); var _chunkMEG7RDX7cjs = require('./chunk-MEG7RDX7.cjs'); // src/sveltekit/index.ts var _async_hooks = require('async_hooks'); var _cookies = require('@edge-runtime/cookies'); function hasOwnProperty(obj, prop) { return obj.hasOwnProperty(prop); } var headersMap = /* @__PURE__ */ new WeakMap(); var cookiesMap = /* @__PURE__ */ new WeakMap(); function sealHeaders(headers) { const cached = headersMap.get(headers); if (cached !== void 0) return cached; const sealed = _chunkJYRFFBKMcjs.HeadersAdapter.seal(headers); headersMap.set(headers, sealed); return sealed; } function sealCookies(headers) { const cached = cookiesMap.get(headers); if (cached !== void 0) return cached; const sealed = _chunkJYRFFBKMcjs.RequestCookiesAdapter.seal(new (0, _cookies.RequestCookies)(headers)); cookiesMap.set(headers, sealed); return sealed; } async function resolveObjectPromises(obj) { const entries = Object.entries(obj); const resolvedEntries = await Promise.all( entries.map(async ([key, promise]) => { const value = await promise; return [key, value]; }) ); return Object.fromEntries(resolvedEntries); } function getDecide(definition) { return function decide(params) { if (typeof definition.decide === "function") { return definition.decide(params); } if (typeof _optionalChain([definition, 'access', _ => _.adapter, 'optionalAccess', _2 => _2.decide]) === "function") { return definition.adapter.decide({ key: definition.key, ...params }); } throw new Error( `@vercel/flags: No decide function provided for ${definition.key}` ); }; } function flag(definition) { const decide = getDecide(definition); const flagImpl = async function flagImpl2() { const store = flagStorage.getStore(); if (!store) { throw new Error("@vercel/flags: context not found"); } if (hasOwnProperty(store.usedFlags, definition.key)) { const valuePromise2 = store.usedFlags[definition.key]; if (typeof valuePromise2 !== "undefined") { return valuePromise2; } } const overridesCookie = store.event.cookies.get("vercel-flag-overrides"); const overrides = overridesCookie ? await _chunkJYRFFBKMcjs.decrypt.call(void 0, overridesCookie, store.secret) : void 0; if (overrides && hasOwnProperty(overrides, definition.key)) { const value2 = overrides[definition.key]; if (typeof value2 !== "undefined") { _chunkJYRFFBKMcjs.reportValue.call(void 0, definition.key, value2); store.usedFlags[definition.key] = Promise.resolve(value2); return value2; } } const valuePromise = decide( { headers: sealHeaders(store.event.request.headers), cookies: sealCookies(store.event.request.headers) }, // @ts-expect-error not part of the type, but we supply it for convenience { event: store.event } ); store.usedFlags[definition.key] = valuePromise; const value = await valuePromise; _chunkJYRFFBKMcjs.reportValue.call(void 0, definition.key, value); return value; }; flagImpl.key = definition.key; flagImpl.defaultValue = definition.defaultValue; flagImpl.origin = definition.origin; flagImpl.description = definition.description; flagImpl.options = definition.options; flagImpl.decide = decide; return flagImpl; } function getProviderData(flags) { const definitions = Object.values(flags).reduce( (acc, d) => { acc[d.key] = { options: _chunkAVMIIWOFcjs.normalizeOptions.call(void 0, d.options), origin: d.origin, description: d.description }; return acc; }, {} ); return { definitions, hints: [] }; } function createContext(event, secret) { return { event, secret, usedFlags: {} }; } var flagStorage = new (0, _async_hooks.AsyncLocalStorage)(); function createHandle({ secret, flags }) { return function handle({ event, resolve }) { if (flags && // avoid creating the URL object for every request by checking with includes() first event.request.url.includes("/.well-known/") && new URL(event.request.url).pathname === "/.well-known/vercel/flags") { return handleWellKnownFlagsRoute(event, secret, flags); } const flagContext = createContext(event, secret); return flagStorage.run( flagContext, () => resolve(event, { transformPageChunk: async ({ html }) => { const store = flagStorage.getStore(); if (!store || Object.keys(store.usedFlags).length === 0) return html; const encryptedFlagValues = await _chunkJYRFFBKMcjs.encrypt.call(void 0, await resolveObjectPromises(store.usedFlags), secret ); return html.replace( "</body>", `<script type="application/json" data-flag-values>${_chunkMEG7RDX7cjs.safeJsonStringify.call(void 0, encryptedFlagValues)}</script></body>` ); } }) ); }; } async function handleWellKnownFlagsRoute(event, secret, flags) { const access = await _chunkJYRFFBKMcjs.verifyAccess.call(void 0, event.request.headers.get("Authorization"), secret ); if (!access) return new Response(null, { status: 401 }); return Response.json(getProviderData(flags)); } exports.createHandle = createHandle; exports.flag = flag; exports.getProviderData = getProviderData; //# sourceMappingURL=sveltekit.cjs.map