deno.land / x / esm@v135_2 / packages / esm-worker / src / index.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875import { compareVersions, satisfies, validate } from "compare-versions";import { getBuildTargetFromUA, targets } from "esm-compat";import type { Context, HttpMetadata, Middleware, PackageInfo, PackageRegistryInfo, WorkerStorage,} from "../types/index.d.ts";import { assetsExts, cssPackages, STABLE_VERSION, stableBuild, VERSION } from "./consts.ts";import { getMimeType } from "./content_type.ts";import { asKV, checkPreflight, copyHeaders, corsHeaders, err, errPkgNotFound, fixPkgVersion, hashText, hasTargetSegment, redirect, splitBy, trimPrefix,} from "./utils.ts";
const regexpNpmNaming = /^[a-zA-Z0-9][\w\.\-]*$/;const regexpFullVersion = /^\d+\.\d+\.\d+/;const regexpCommitish = /^[a-f0-9]{10,}$/;const regexpBuildVersion = /^(v\d+|stable)$/;const regexpBuildVersionPrefix = /^\/(v\d+|stable)\//;
const version = `v${VERSION}`;const defaultNpmRegistry = "https://registry.npmjs.org";const defaultEsmServerOrigin = "https://esm.sh";const immutableCache = "public, max-age=31536000, immutable";
const noopStorage: WorkerStorage = { get: () => Promise.resolve(null), put: () => Promise.resolve(),};
async function fetchOrigin( req: Request, env: Env, ctx: Context, uri: string, resHeaders: Headers,): Promise<Response> { const headers = new Headers(); copyHeaders( headers, req.headers, "Content-Type", "Referer", "User-Agent", "X-Esm-Worker-Version", "X-Forwarded-For", "X-Real-Ip", "X-Real-Origin", ); if (!headers.has("X-Esm-Worker-Version")) { headers.set("X-Esm-Worker-Version", `v${VERSION}`); } if (!headers.has("X-Real-Origin")) { headers.set("X-Real-Origin", ctx.url.origin); } if (env.ESM_TOKEN) { headers.set("Authorization", `Bearer ${env.ESM_TOKEN}`); } const res = await fetch( new URL(uri, env.ESM_ORIGIN ?? defaultEsmServerOrigin), { method: req.method === "HEAD" ? "GET" : req.method, body: req.body, headers, redirect: "manual", }, ); const buffer = await res.arrayBuffer(); if (!res.ok) { // CF default error page(html) if ( res.status === 500 && res.headers.get("Content-Type")?.startsWith("text/html") ) { return new Response("Bad Gateway", { status: 502, headers: resHeaders }); } // redirects if (res.status === 301 || res.status === 302) { return redirect(res.headers.get("Location")!, res.status); } // fix cache-control by status code if (res.headers.has("Cache-Control")) { resHeaders.set("Cache-Control", res.headers.get("Cache-Control")!); } else if (res.status === 400) { resHeaders.set("Cache-Control", immutableCache); } copyHeaders(resHeaders, res.headers, "Content-Type"); return new Response(buffer, { status: res.status, headers: resHeaders }); } copyHeaders( resHeaders, res.headers, "Cache-Control", "Content-Type", "Content-Length", "X-Esm-Id", "X-Typescript-Types", ); const exposedHeaders = []; for (const key of ["X-Esm-Id", "X-Typescript-Types"]) { if (resHeaders.has(key)) { exposedHeaders.push(key); } } if (exposedHeaders.length > 0) { resHeaders.set("Access-Control-Expose-Headers", exposedHeaders.join(", ")); } return new Response(buffer, { headers: resHeaders });}
async function fetchOriginWithKVCache( req: Request, env: Env, ctx: Context, path: string, gzip?: boolean,): Promise<Response> { let storeKey = path.slice(1); if (storeKey.startsWith("stable/")) { storeKey = `v${STABLE_VERSION}/` + storeKey.slice(7); } else if (storeKey.startsWith("+")) { storeKey = `modules/` + storeKey; } const headers = corsHeaders(); const [pathname] = splitBy(path, "?", true); const R2 = Reflect.get(env, "R2") as R2Bucket | undefined ?? noopStorage; const KV = Reflect.get(env, "KV") as KVNamespace | undefined ?? asKV(R2); const fromWorker = req.headers.has("X-Real-Origin"); const isModule = !( ctx.url.searchParams.has("raw") || pathname.endsWith(".d.ts") || pathname.endsWith(".d.mts") || pathname.endsWith(".map") );
if (!fromWorker) { if (isModule) { const { value, metadata } = await KV.getWithMetadata<HttpMetadata>( storeKey, "stream", ); if (value && metadata) { let body = value as ReadableStream<Uint8Array>; if (gzip && typeof DecompressionStream !== "undefined") { body = body.pipeThrough(new DecompressionStream("gzip")); } headers.set("Content-Type", metadata.contentType); headers.set("Cache-Control", immutableCache); const exposedHeaders = []; if (metadata.buildId) { headers.set("X-Esm-Id", metadata.buildId); exposedHeaders.push("X-Esm-Id"); } if (metadata.dts) { headers.set("X-TypeScript-Types", metadata.dts); exposedHeaders.push("X-TypeScript-Types"); } if (exposedHeaders.length > 0) { headers.set( "Access-Control-Expose-Headers", exposedHeaders.join(", "), ); } headers.set("X-Content-Source", "esm-worker"); return new Response(body, { headers }); } } else { const obj = await R2.get(storeKey); if (obj) { const contentType = obj.httpMetadata?.contentType || getMimeType(path); headers.set("Content-Type", contentType); headers.set("Cache-Control", immutableCache); headers.set("X-Content-Source", "esm-worker"); return new Response(obj.body, { headers }); } } }
const res = await fetchOrigin(req, env, ctx, path, headers); if (!res.ok) { return res; }
const buffer = await res.arrayBuffer(); const contentType = res.headers.get("Content-Type") || getMimeType(path); const cacheControl = res.headers.get("Cache-Control"); const buildId = res.headers.get("X-Esm-Id"); const dts = res.headers.get("X-TypeScript-Types"); const exposedHeaders = [];
headers.set("Content-Type", contentType); if (cacheControl) { headers.set("Cache-Control", cacheControl); } if (buildId) { headers.set("X-Esm-Id", buildId); exposedHeaders.push("X-Esm-Id"); } if (dts) { headers.set("X-TypeScript-Types", dts); exposedHeaders.push("X-TypeScript-Types"); } if (exposedHeaders.length > 0) { headers.set("Access-Control-Expose-Headers", exposedHeaders.join(", ")); } headers.set("X-Content-Source", "origin-server");
// save to KV/R2 if immutable if (!fromWorker && cacheControl?.includes("immutable")) { if (!isModule) { ctx.waitUntil(R2.put(storeKey, buffer.slice(0), { httpMetadata: { contentType }, })); } else { let value: ArrayBuffer | ReadableStream = buffer.slice(0); if (gzip && typeof CompressionStream !== "undefined") { value = new Response(value).body.pipeThrough<Uint8Array>( new CompressionStream("gzip"), ); } ctx.waitUntil(KV.put(storeKey, value, { metadata: { contentType, dts, buildId }, })); } }
return new Response(buffer, { headers });}
async function fetchOriginWithR2Cache( req: Request, ctx: Context, env: Env, pathname: string,): Promise<Response> { const resHeaders = corsHeaders(); const r2 = Reflect.get(env, "R2") as R2Bucket | undefined ?? noopStorage; const ret = await r2.get(pathname.slice(1)); if (ret) { resHeaders.set( "Content-Type", ret.httpMetadata?.contentType || getMimeType(pathname), ); resHeaders.set("Cache-Control", immutableCache); resHeaders.set("X-Content-Source", "esm-worker"); return new Response(ret.body as ReadableStream<Uint8Array>, { headers: resHeaders, }); }
const res = await fetchOrigin(req, env, ctx, pathname, resHeaders); if (res.ok) { const contentType = res.headers.get("content-type") || getMimeType(pathname); const buffer = await res.arrayBuffer(); ctx.waitUntil(r2.put(pathname.slice(1), buffer.slice(0), { httpMetadata: { contentType }, })); resHeaders.set("Content-Type", contentType); resHeaders.set("Cache-Control", immutableCache); resHeaders.set("X-Content-Source", "origin-server"); return new Response(buffer, { headers: resHeaders }); } return res;}
function withESMWorker(middleware?: Middleware) { const cachePromise = caches.open(`esm.sh/v${VERSION}`);
async function handler( req: Request, env: Env, context: ExecutionContext, ): Promise<Response> { const resp = checkPreflight(req); if (resp) { return resp; }
const url = new URL(req.url); const ua = req.headers.get("User-Agent"); const cache = await cachePromise; const withCache: Context["withCache"] = async (fetcher, options) => { const isHeadMethod = req.method === "HEAD"; const hasPinedTarget = targets.has(url.searchParams.get("target") ?? ""); const cacheKey = new URL(url); const varyUA = options?.varyUA && !hasPinedTarget && !url.hostname.endsWith(".d.ts") && !url.hostname.endsWith(".d.mts") && !url.searchParams.has("raw"); if (varyUA) { const target = getBuildTargetFromUA(ua); cacheKey.searchParams.set("target", target); //! don't delete this line, it used to ensure KV/R2 cache respecting different UA url.searchParams.set("target", target); } for (const key of ["x-real-origin", "x-esm-worker-version"]) { const value = req.headers.get(key); if (value) { cacheKey.searchParams.set(key, value); } } let res = await cache.match(cacheKey); if (res) { if (isHeadMethod) { const { status, headers } = res; return new Response(null, { status, headers }); } return res; } res = await fetcher(); if (varyUA) { const headers = new Headers(res.headers); headers.append("Vary", "User-Agent"); res = new Response(res.body, { status: res.status, headers }); } if ( res.ok && res.headers.get("Cache-Control")?.startsWith("public, max-age=") ) { context.waitUntil(cache.put(cacheKey, res.clone())); } if (isHeadMethod) { const { status, headers } = res; return new Response(null, { status, headers }); } return res; }; const ctx: Context = { cache, url, data: {}, waitUntil: (p: Promise<any>) => context.waitUntil(p), withCache, };
let pathname = decodeURIComponent(url.pathname);
// strip trailing slash if (pathname !== "/" && pathname.endsWith("/")) { pathname = pathname.slice(0, -1); }
// return the CLI script if ( ua === "undici" || ua?.startsWith("Node/") || ua?.startsWith("Deno/") || ua?.startsWith("Bun/") ) { if (pathname === "/" || /^\/v\d+\/?$/.test(pathname)) { return ctx.withCache( () => fetchOrigin(req, env, ctx, pathname, corsHeaders()), { varyUA: true }, ); } }
switch (pathname) { case "/error.js": return ctx.withCache( () => fetchOrigin( req, env, ctx, pathname + url.search, corsHeaders(), ), { varyUA: true }, );
case "/status.json": return fetchOrigin(req, env, ctx, pathname, corsHeaders());
case "/esma-target": return ctx.withCache( () => { const headers = corsHeaders(); headers.set("cache-control", immutableCache); return new Response(getBuildTargetFromUA(ua), { headers }); }, { varyUA: true }, ); }
if (middleware) { const resp = await middleware(req, env, ctx); if (resp) { return resp; } }
if ( req.method === "POST" && (pathname === "/build" || pathname === "/transform") ) { const input = await req.text(); const key = "esm-build-" + await hashText(input); const storage = Reflect.get(env, "R2") as R2Bucket | undefined ?? noopStorage; const KV = Reflect.get(env, "KV") as KVNamespace | undefined ?? asKV(storage); const { value } = await KV.getWithMetadata(key, "stream"); if (value) { const headers = corsHeaders(); headers.set("content-type", "application/json"); headers.set( "cache-control", "private, no-store, no-cache, must-revalidate", ); headers.set("X-Content-Source", "esm-worker"); return new Response(value, { headers, }); } const res = await fetchOrigin( new Request(req.url, { method: "POST", headers: req.headers, body: input, }), env, ctx, `${pathname}${url.search}`, corsHeaders(), ); if (res.status !== 200) { return res; } const body = await res.arrayBuffer(); ctx.waitUntil(KV.put(key, body)); return new Response(body, { status: res.status, headers: res.headers, }); }
if (req.method !== "GET" && req.method !== "HEAD") { return err("Method Not Allowed", 405); }
// ban malicious requests if ( pathname === "/favicon.ico" || pathname.startsWith("/.") || pathname.endsWith(".php") ) { return ctx.withCache( () => new Response(null, { status: 404, headers: { "cache-control": immutableCache }, }), ); }
// landing page or embed files if (pathname === "/" || pathname.startsWith("/embed/")) { return fetchOrigin( req, env, ctx, `${pathname}${url.search}`, corsHeaders(), ); }
// fix `/jsx-runtime` suffix in query, normally it happens with import maps if ( url.search.endsWith("/jsx-runtime") || url.search.endsWith("/jsx-dev-runtime") ) { const [q, jsxRuntime] = splitBy(url.search, "/", true); pathname = pathname + "/" + jsxRuntime; url.pathname = pathname; url.search = q; }
// strip loc if (/:\d+:\d+$/.test(pathname)) { pathname = splitBy(pathname, ":")[0]; }
// singleton build module if (pathname.startsWith("/+")) { return ctx.withCache( () => fetchOriginWithKVCache(req, env, ctx, pathname + url.search), { varyUA: true }, ); }
let buildVersion = "v" + VERSION;
// check pinned build version const hasBuildVerPrefix = regexpBuildVersionPrefix.test(pathname); const hasBuildVerQuery = !hasBuildVerPrefix && regexpBuildVersion.test(url.searchParams.get("pin") ?? ""); if (hasBuildVerPrefix) { const a = pathname.split("/"); buildVersion = a[1]; pathname = "/" + a.slice(2).join("/"); } else if (hasBuildVerQuery) { buildVersion = url.searchParams.get("pin")!; }
if ( pathname === "/build" || pathname === "/run" || pathname === "/hot" ) { if (!hasBuildVerPrefix && !hasBuildVerQuery) { return redirect( new URL(`/${buildVersion}${pathname}${url.search}`, url), 302, ); } return ctx.withCache(() => fetchOrigin( req, env, ctx, `/${buildVersion}${pathname}${url.search}`, corsHeaders(), ), { varyUA: true }); }
const gh = pathname.startsWith("/gh/"); if (gh) { pathname = "/@" + pathname.slice(4); } else if (pathname.startsWith("/jsr/@")) { const segs = pathname.split("/"); pathname = "/@jsr/" + segs[2].slice(1) + "__" + segs[3]; if (segs.length > 4) { pathname += "/" + segs.slice(4).join("/"); } }
// strip external all marker const hasExternalAllMarker = pathname.startsWith("/*"); if (hasExternalAllMarker) { pathname = "/" + pathname.slice(2); }
if ( hasBuildVerPrefix && ( pathname === "/node.ns.d.ts" || pathname === "/hot.d.ts" || ( pathname.startsWith("/node_") && pathname.endsWith(".js") && !pathname.slice(1).includes("/") ) ) ) { return ctx.withCache(() => fetchOriginWithKVCache( req, env, ctx, `/${buildVersion}${pathname}${url.search}`, true, ), { varyUA: true }); }
let packageScope = ""; let packageName = ""; let packageVersion = ""; let subPath = ""; let extraQuery = "";
if (pathname.startsWith("/@")) { const [scope, name, ...rest] = decodeURIComponent(pathname).slice(2).split("/"); packageScope = "@" + scope; [packageName, packageVersion] = splitBy(name, "@"); if (rest.length > 0) { subPath = "/" + rest.join("/"); } } else { const [name, ...rest] = decodeURIComponent(pathname).slice(1).split( "/", ); [packageName, packageVersion] = splitBy(name, "@"); if (rest.length > 0) { subPath = "/" + rest.join("/"); } }
if (packageScope !== "" && !regexpNpmNaming.test(packageScope.slice(1))) { return err(`Invalid scope name '${packageScope}'`, 400); }
if (packageName === "") { return err("Invalid path", 400); }
const fromEsmsh = packageName.startsWith("~") && regexpCommitish.test(packageName.slice(1)); if (!fromEsmsh && !regexpNpmNaming.test(packageName)) { return err(`Invalid package name '${packageName}'`, 400); }
let pkgId = packageName; if (packageScope) { pkgId = packageScope + "/" + packageName; if (gh) { // strip the leading `@` pkgId = pkgId.slice(1); } }
// format package version if (packageVersion) { [packageVersion, extraQuery] = splitBy(packageVersion, "&"); if (!gh) { if ( packageVersion.startsWith("=") || packageVersion.startsWith("v") ) { packageVersion = packageVersion.slice(1); } else if (/^\d+$/.test(packageVersion)) { packageVersion = "~" + packageVersion; } else if (/^\d+.\d+$/.test(packageVersion)) { packageVersion = "~" + packageVersion; } } }
if (fromEsmsh) { packageVersion = "0.0.0"; }
// redirect to commit-ish version if ( gh && !( packageVersion && ( regexpCommitish.test(packageVersion) || regexpFullVersion.test(trimPrefix(packageVersion, "v")) ) ) ) { return ctx.withCache(() => fetchOrigin( req, env, ctx, url.pathname + url.search, corsHeaders(), ) ); }
// redirect to specific version if (!gh && !(packageVersion && regexpFullVersion.test(packageVersion))) { return ctx.withCache(async () => { const headers = new Headers(); if (env.NPM_TOKEN) { headers.set("Authorization", `Bearer ${env.NPM_TOKEN}`); } let registry = env.NPM_REGISTRY ?? defaultNpmRegistry; if (pkgId.startsWith("@jsr/")) { registry = "https://npm.jsr.io"; } const res = await fetch( new URL(pkgId, registry), { headers }, ); if (!res.ok) { if (res.status === 404 || res.status === 401) { return errPkgNotFound(pkgId); } return new Response(res.body, { status: res.status, headers: corsHeaders(), }); } const regInfo: PackageRegistryInfo = await res.json(); let prefix = "/"; if (hasBuildVerPrefix) { prefix += buildVersion + "/"; } if (hasExternalAllMarker) { prefix += "*"; } let pkgName = pkgId; if (pkgId.startsWith("@jsr/") && !hasTargetSegment(subPath)) { pkgName = "jsr/@" + pkgName.slice(5).replace("__", "/"); } const eq = extraQuery ? "&" + extraQuery : ""; const distVersion = regInfo["dist-tags"] ?.[packageVersion || "latest"]; if (distVersion) { const uri = `${prefix}${pkgName}@${fixPkgVersion(pkgId, distVersion)}${eq}${subPath}${url.search}`; return redirect(new URL(uri, url), 302); } const versions = Object.keys(regInfo.versions ?? []).filter(validate) .sort(compareVersions); if (!packageVersion) { const latestVersion = versions.filter((v) => !v.includes("-")).pop() ?? versions.pop(); if (latestVersion) { const uri = `${prefix}${pkgName}@${fixPkgVersion(pkgId, latestVersion)}${eq}${subPath}${url.search}`; return redirect(new URL(uri, url), 302); } } try { const arr = packageVersion.includes("-") ? versions : versions.filter((v) => !v.includes("-")); for (let i = arr.length - 1; i >= 0; i--) { const v = arr[i]; if (satisfies(v, packageVersion)) { const uri = `${prefix}${pkgName}@${fixPkgVersion(pkgId, v)}${eq}${subPath}${url.search}`; return redirect(new URL(uri, url), 302); } } } catch (_) { // error of `satisfies` function return err(`Invalid package version '${packageVersion}'`); } return err("Could not get the package version"); }); }
// redirect `/@types/PKG` to `.d.ts` files if ( pkgId.startsWith("@types/") && (subPath === "" || !subPath.endsWith(".d.ts")) ) { return ctx.withCache(async () => { let p = `/${buildVersion}${pathname}`; if (subPath !== "") { p += "~.d.ts"; } else { const headers = new Headers(); if (env.NPM_TOKEN) { headers.set("Authorization", `Bearer ${env.NPM_TOKEN}`); } const res = await fetch( new URL(pkgId, env.NPM_REGISTRY ?? defaultNpmRegistry), { headers }, ); if (!res.ok) { if (res.status === 404 || res.status === 401) { return errPkgNotFound(pkgId); } return new Response(res.body, { status: res.status, headers }); } const pkgJson: PackageInfo = await res.json(); p += "/" + (pkgJson.types || pkgJson.typings || pkgJson.main || "index.d.ts"); } return redirect(new URL(p, url), 301); }); }
// redirect to main css for CSS packages let css: string | undefined; if (!gh && (css = cssPackages[pkgId]) && subPath === "") { return redirect(new URL(`/${pkgId}@${packageVersion}/${css}`, url), 301); }
// redirect to real package css file: `/PKG?css` -> `/v100/PKG/es2022/pkg.css` if (url.searchParams.has("css") && subPath === "") { let prefix = `/${buildVersion}`; if (gh) { prefix += "/gh"; } let target = url.searchParams.get("target"); if (!target || !targets.has(target)) { target = getBuildTargetFromUA(ua); } const pined = hasBuildVerPrefix || hasBuildVerQuery; return redirect( new URL( `${prefix}/${pkgId}@${packageVersion}/${target}/${packageName}.css`, url, ), pined ? 301 : 302, ); }
// redirect to real wasm file: `/v100/PKG/es2022/foo.wasm` -> `PKG/foo.wasm` if (hasBuildVerPrefix && hasTargetSegment(subPath) && (subPath.endsWith(".wasm") || subPath.endsWith(".json"))) { return ctx.withCache(() => { return fetchOrigin(req, env, ctx, url.pathname, corsHeaders()); }); }
// npm assets if (!hasBuildVerPrefix && subPath !== "") { const ext = splitBy(subPath, ".", true)[1]; // append missed build version prefix for dts // example: `/@types/react/index.d.ts` -> `/v100/@types/react/index.d.ts` if (subPath.endsWith(".d.ts") || subPath.endsWith(".d.mts")) { return redirect(new URL("/v" + VERSION + url.pathname, url), 301); } // use origin server response for `*.wasm?module` if (ext === "wasm" && url.searchParams.has("module")) { return ctx.withCache(() => { return fetchOrigin( req, env, ctx, url.pathname + "?module", corsHeaders(), ); }); } if (assetsExts.has(ext)) { return ctx.withCache(() => { const prefix = gh ? "/gh" : ""; const pathname = `${prefix}/${pkgId}@${packageVersion}${subPath}`; return fetchOriginWithR2Cache(req, ctx, env, pathname); }); } }
// apply extraQuery if (extraQuery) { const params = new URLSearchParams(extraQuery); params.forEach((val, key) => { url.searchParams.set(key, val); }); } if (url.hostname === "raw.esm.sh") { url.searchParams.set("raw", ""); }
if ( hasBuildVerPrefix && (subPath.endsWith(".d.ts") || hasTargetSegment(subPath)) ) { return ctx.withCache(() => { let prefix = `/${buildVersion}`; if (gh) { prefix += "/gh"; } const path = `${prefix}/${pkgId}@${packageVersion}${subPath}${url.search}`; return fetchOriginWithKVCache(req, env, ctx, path, true); }); }
return ctx.withCache(() => { let prefix = ""; if (hasBuildVerPrefix) { prefix += `/${buildVersion}`; } else if (stableBuild.has(pkgId)) { prefix += `/v${STABLE_VERSION}`; } if (gh) { prefix += "/gh"; } const marker = hasExternalAllMarker ? "*" : ""; const path = `${prefix}/${marker}${pkgId}@${packageVersion}${subPath}${url.search}`; return fetchOriginWithKVCache(req, env, ctx, path); }, { varyUA: true }); }
return { fetch: handler };}
export { checkPreflight, corsHeaders, getBuildTargetFromUA, hashText, redirect, targets, version, withESMWorker };
Version Info