mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-21 05:50:55 +08:00
- Compile production program loading across module graphs, packages, and configuration - Preserve optional defaults and support runtime URL bases and regex split captures - Isolate host execution services and initialize lowering tables outside module cycles
52 lines
2.7 KiB
TypeScript
52 lines
2.7 KiB
TypeScript
// Both inputs arrive at runtime: the compiler cannot fold these URL calls.
|
|
function resolve(input: string, base: string): void {
|
|
try {
|
|
const value = new URL(input, base);
|
|
console.log(value.href, value.protocol, value.host, value.pathname, value.search, value.hash);
|
|
} catch (error) {
|
|
if (error instanceof Error) console.log(error.name, error.message);
|
|
}
|
|
}
|
|
|
|
const http = "https://user:p@host:444/a/b?before#frag";
|
|
for (const input of ["", "#", "#next", "?", "?q#f", "../c", "/x", "//new/x", "https:c", "https:/c", "https://c", "https:", "other:x"])
|
|
resolve(input, http);
|
|
for (const input of ["./a", "../a", "../../../../a", "%2e%2e/a", ".%2e/a", "a/./b/../c", "a//b", "a/..", "a/.", " a b ", "a\tb\nc\rd", "a\\b", "\\root", "\\\\new\\path"])
|
|
resolve(input, http);
|
|
for (const input of ["/root", "../..", "../../..", "../c", "D:/root", "D|/root", "file:foo", "//server/share", "//D:/root", "/D|/root"])
|
|
resolve(input, "file:///C:/a/b");
|
|
for (const input of ["a", "/a", "../a", "//new/path", "?query", "#hash", ""])
|
|
resolve(input, "file://server/share/dir/file?query#hash");
|
|
for (const input of ["#next", "", "?q", "x", "http://host/", "data:next"])
|
|
resolve(input, "data:a?b#f");
|
|
for (const base of ["custom://Host/a/b", "custom:/a/b", "custom://Host", "http://host/", "file:///tmp/project/main.ts"])
|
|
for (const input of ["next", "../next", "?q", "#f", "/root", "//Other/x"])
|
|
resolve(input, base);
|
|
resolve("https://valid.example/", "invalid");
|
|
resolve("relative", "invalid");
|
|
resolve("//[bad]/", http);
|
|
resolve("//host:65536/", http);
|
|
resolve("é/你好?x=é#你好", http);
|
|
resolve("child", " HTTP://EXAMPLE.COM:80/a/../b?x#y ");
|
|
|
|
let order = "";
|
|
function input(): string { order += "input;"; return "../next.ts"; }
|
|
function base(): string { order += "base;"; return "file:///tmp/project/main.ts"; }
|
|
console.log(new URL(input(), base()).href, order);
|
|
|
|
function optional(input: string | URL, base?: string | URL): void {
|
|
try { console.log(new URL(input, base).href); }
|
|
catch (error) { if (error instanceof Error) console.log(error.name, error.message); }
|
|
}
|
|
optional("https://absolute.example/a");
|
|
optional("relative");
|
|
optional("next", new URL("https://base.example/dir/"));
|
|
optional(new URL("https://input.example/a"), "https://base.example/");
|
|
optional("../x", "https://base.example/a/b");
|
|
console.log(new URL("https://absolute.example/", void (order += "undefined;")).href, order);
|
|
|
|
const coercedInput = { toString: (): string => { order += "inputString;"; return "../coerced"; } };
|
|
function inputObject(): { toString: () => string } { order += "inputObject;"; return coercedInput; }
|
|
function baseObject(): string { order += "baseObject;"; return "https://base.example/a/b"; }
|
|
console.log(new URL(inputObject(), baseObject()).href, order);
|