Skip to content

Commit

Permalink
Add version prefix for internal srcipts/types
Browse files Browse the repository at this point in the history
  • Loading branch information
ije committed Mar 2, 2024
1 parent e822f97 commit ed745df
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 192 deletions.
214 changes: 103 additions & 111 deletions packages/esm-worker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ import {
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 regexpInternalScript = /^\/v[1-9]\d+\/(build|run|hot)$/;
const regexpInternalFile = /^\/v[1-9]\d+\/(?:node_\w+\.js|(?:node\.ns|hot)\.d\.ts)$/;
const regexpVersionPrefix = /^\/v[1-9]\d+\//;

const version = `v${VERSION}`;
const defaultNpmRegistry = "https://registry.npmjs.org";
Expand Down Expand Up @@ -285,14 +286,6 @@ function withESMWorker(middleware?: Middleware) {
}

const url = new URL(req.url);
if (env.LEGACY_WORKER) {
const hasBuildVersionPrefix = url.pathname.startsWith("/v") && regexpBuildVersionPrefix.test(url.pathname);
const hasPinQuery = url.searchParams.has("pin") && regexpBuildVersion.test(url.searchParams.get("pin"));
if (hasBuildVersionPrefix || hasPinQuery) {
return env.LEGACY_WORKER.fetch(req.clone());
}
}

const ua = req.headers.get("User-Agent");
const withCache: Context["withCache"] = async (fetcher, options) => {
const { pathname, searchParams } = url;
Expand Down Expand Up @@ -347,52 +340,24 @@ function withESMWorker(middleware?: Middleware) {
withCache,
};

let pathname = decodeURIComponent(url.pathname);
let pathname = url.pathname;

// ban malicious requests
if (pathname.startsWith("/.") || pathname.endsWith(".php")) {
return ctx.withCache(() =>
new Response(null, {
status: 404,
headers: { "cache-control": immutableCache },
})
);
}

// strip trailing slash
if (pathname !== "/" && pathname.endsWith("/")) {
pathname = pathname.slice(0, -1);
}

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")
) {
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 ?? dumpStorage;
Expand Down Expand Up @@ -426,56 +391,56 @@ function withESMWorker(middleware?: Middleware) {
}
const body = await res.arrayBuffer();
ctx.waitUntil(KV.put(key, body));
return new Response(body, {
status: res.status,
headers: res.headers,
});
return new Response(body, { status: res.status, headers: res.headers });
}

if (req.method !== "GET" && req.method !== "HEAD") {
return err("Method Not Allowed", 405);
}
switch (pathname) {
case "/error.js":
return ctx.withCache(() => fetchOrigin(req, env, ctx, pathname + url.search, corsHeaders()));

// ban malicious requests
if (
pathname === "/favicon.ico" ||
pathname.startsWith("/.") ||
pathname.endsWith(".php")
) {
return ctx.withCache(
() =>
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 },
);

case "/favicon.ico": {
return ctx.withCache(() =>
new Response(null, {
status: 404,
headers: { "cache-control": immutableCache },
}),
);
})
);
}

case "/build":
case "/run":
case "/hot": {
return redirect(new URL(`/${version}${pathname}${url.search}`, url), 302);
}
}

// landing page or embed files
if (pathname === "/" || pathname.startsWith("/embed/")) {
return fetchOrigin(
req,
env,
ctx,
`${pathname}${url.search}`,
corsHeaders(),
);
if (middleware) {
const resp = await middleware(req, env, ctx);
if (resp) {
return resp;
}
}

// 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;
if (req.method !== "GET" && req.method !== "HEAD") {
return err("Method Not Allowed", 405);
}

// strip loc
if (/:\d+:\d+$/.test(pathname)) {
pathname = splitBy(pathname, ":")[0];
// return the default landing page or embed files
if (pathname === "/" || pathname.startsWith("/embed/")) {
return fetchOrigin(req, env, ctx, `${pathname}${url.search}`, corsHeaders());
}

// singleton build module
Expand All @@ -486,21 +451,66 @@ function withESMWorker(middleware?: Middleware) {
);
}

const startsWithV = pathname.startsWith("/v");

if (
pathname === "/build" ||
pathname === "/run" ||
pathname === "/hot"
startsWithV &&
(pathname.endsWith("/build") || pathname.endsWith("/run") || pathname.endsWith("/hot")) &&
regexpInternalScript.test(pathname)
) {
return ctx.withCache(() =>
fetchOrigin(
fetchOriginWithKVCache(
req,
env,
ctx,
`${pathname}${url.search}`,
corsHeaders(),
false,
), { varyUA: true });
}

if (
startsWithV &&
(pathname.endsWith(".d.ts") || pathname.endsWith(".js")) &&
regexpInternalFile.test(pathname)
) {
return ctx.withCache(() =>
fetchOriginWithKVCache(
req,
env,
ctx,
`${pathname}${url.search}`,
true,
), { varyUA: true });
}

// use legacy worker if the bild version is specified in the path or query
if (env.LEGACY_WORKER) {
const hasVersionPrefix = (startsWithV && regexpVersionPrefix.test(pathname)) || pathname.startsWith("/stable");
const hasPinQuery = url.searchParams.has("pin");
if (hasVersionPrefix || hasPinQuery) {
return env.LEGACY_WORKER.fetch(req.clone());
}
}

// decode pathname
pathname = decodeURIComponent(pathname);

// 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];
}

const gh = pathname.startsWith("/gh/");
if (gh) {
pathname = "/@" + pathname.slice(4);
Expand All @@ -518,24 +528,6 @@ function withESMWorker(middleware?: Middleware) {
pathname = "/" + pathname.slice(2);
}

if (
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,
`${pathname}${url.search}`,
true,
), { varyUA: true });
}

let packageScope = "";
let packageName = "";
let packageVersion = "";
Expand Down
8 changes: 4 additions & 4 deletions server/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ rebuild:
}
if specifier == "fsevents" {
return api.OnResolveResult{
Path: fmt.Sprintf("%s/node_fsevents.js", cfg.CdnBasePath),
Path: fmt.Sprintf("%s/v%d/node_fsevents.js", cfg.CdnBasePath, VERSION),
External: true,
}, nil
}
Expand Down Expand Up @@ -784,7 +784,7 @@ rebuild:
}
fmt.Fprintf(header, "%s", js)
} else {
fmt.Fprintf(header, `import __Process$ from "%s/node_process.js";%s`, cfg.CdnBasePath, EOL)
fmt.Fprintf(header, `import __Process$ from "%s/v%d/node_process.js";%s`, cfg.CdnBasePath, VERSION, EOL)
}
}
}
Expand Down Expand Up @@ -991,7 +991,7 @@ func (task *BuildTask) resolveExternal(specifier string, kind api.ResolveKind) (
} else {
_, err := embedFS.ReadFile(fmt.Sprintf("server/embed/polyfills/node_%s.js", specifier))
if err == nil {
resolvedPath = fmt.Sprintf("%s/node_%s.js", cfg.CdnBasePath, specifier)
resolvedPath = fmt.Sprintf("%s/v%d/node_%s.js", cfg.CdnBasePath, VERSION, specifier)
} else {
resolvedPath = fmt.Sprintf(
"%s/error.js?type=unsupported-node-builtin-module&name=%s&importer=%s",
Expand Down Expand Up @@ -1030,7 +1030,7 @@ func (task *BuildTask) resolveExternal(specifier string, kind api.ResolveKind) (
}
}
if resolvedPath == "" && task.Target != "node" && specifier == "node-fetch" {
resolvedPath = fmt.Sprintf("%s/node_fetch.js", cfg.CdnBasePath)
resolvedPath = fmt.Sprintf("%s/v%d/node_fetch.js", cfg.CdnBasePath, VERSION)
}
// common npm dependency
if resolvedPath == "" {
Expand Down
2 changes: 1 addition & 1 deletion server/dts_transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (task *BuildTask) transformDTS(dts string, aliasDepsPrefix string, marker *
dtsBasePath := fmt.Sprintf("%s%s", task.CdnOrigin, cfg.CdnBasePath)

if pkgName == "@types/node" {
fmt.Fprintf(buf, "/// <reference path=\"%s/node.ns.d.ts\" />\n", dtsBasePath)
fmt.Fprintf(buf, "/// <reference path=\"%s/v%d/node.ns.d.ts\" />\n", dtsBasePath, VERSION)
}

err = walkDts(pass1Buf, buf, func(specifier string, kind string, position int) string {
Expand Down
Loading

0 comments on commit ed745df

Please sign in to comment.