@seanhogg/builderforce-webcontainers-core 2026.10.2 → 2026.10.4
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/dist/build.d.ts +42 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +65 -0
- package/dist/build.js.map +1 -0
- package/dist/buildHost.d.ts +31 -0
- package/dist/buildHost.d.ts.map +1 -0
- package/dist/buildHost.js +125 -0
- package/dist/buildHost.js.map +1 -0
- package/dist/buildHtml.d.ts +28 -0
- package/dist/buildHtml.d.ts.map +1 -0
- package/dist/buildHtml.js +74 -0
- package/dist/buildHtml.js.map +1 -0
- package/dist/bundler.d.ts +129 -0
- package/dist/bundler.d.ts.map +1 -0
- package/dist/bundler.js +79 -0
- package/dist/bundler.js.map +1 -0
- package/dist/check/acquire.d.ts +46 -0
- package/dist/check/acquire.d.ts.map +1 -0
- package/dist/check/acquire.js +179 -0
- package/dist/check/acquire.js.map +1 -0
- package/dist/check/compilerHost.d.ts +22 -0
- package/dist/check/compilerHost.d.ts.map +1 -0
- package/dist/check/compilerHost.js +128 -0
- package/dist/check/compilerHost.js.map +1 -0
- package/dist/check/diagnostics.d.ts +23 -0
- package/dist/check/diagnostics.d.ts.map +1 -0
- package/dist/check/diagnostics.js +28 -0
- package/dist/check/diagnostics.js.map +1 -0
- package/dist/check/index.d.ts +19 -0
- package/dist/check/index.d.ts.map +1 -0
- package/dist/check/index.js +13 -0
- package/dist/check/index.js.map +1 -0
- package/dist/check/projects.d.ts +26 -0
- package/dist/check/projects.d.ts.map +1 -0
- package/dist/check/projects.js +124 -0
- package/dist/check/projects.js.map +1 -0
- package/dist/check/shims.d.ts +29 -0
- package/dist/check/shims.d.ts.map +1 -0
- package/dist/check/shims.js +76 -0
- package/dist/check/shims.js.map +1 -0
- package/dist/check/typeStore.d.ts +57 -0
- package/dist/check/typeStore.d.ts.map +1 -0
- package/dist/check/typeStore.js +89 -0
- package/dist/check/typeStore.js.map +1 -0
- package/dist/check/typecheck.d.ts +29 -0
- package/dist/check/typecheck.d.ts.map +1 -0
- package/dist/check/typecheck.js +91 -0
- package/dist/check/typecheck.js.map +1 -0
- package/dist/compileComponent.d.ts +8 -0
- package/dist/compileComponent.d.ts.map +1 -0
- package/dist/compileComponent.js +22 -0
- package/dist/compileComponent.js.map +1 -0
- package/dist/compileScript.d.ts +19 -4
- package/dist/compileScript.d.ts.map +1 -1
- package/dist/compileScript.js +37 -12
- package/dist/compileScript.js.map +1 -1
- package/dist/components.d.ts +41 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +14 -0
- package/dist/components.js.map +1 -0
- package/dist/detectProject.d.ts +3 -0
- package/dist/detectProject.d.ts.map +1 -1
- package/dist/detectProject.js +16 -6
- package/dist/detectProject.js.map +1 -1
- package/dist/devServer.d.ts +5 -2
- package/dist/devServer.d.ts.map +1 -1
- package/dist/devServer.js +12 -8
- package/dist/devServer.js.map +1 -1
- package/dist/hash.d.ts +2 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +22 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +24 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/installer/bins.d.ts +24 -0
- package/dist/installer/bins.d.ts.map +1 -0
- package/dist/installer/bins.js +56 -0
- package/dist/installer/bins.js.map +1 -0
- package/dist/installer/index.d.ts +14 -0
- package/dist/installer/index.d.ts.map +1 -0
- package/dist/installer/index.js +9 -0
- package/dist/installer/index.js.map +1 -0
- package/dist/installer/install.d.ts +46 -0
- package/dist/installer/install.d.ts.map +1 -0
- package/dist/installer/install.js +245 -0
- package/dist/installer/install.js.map +1 -0
- package/dist/installer/lockfile.d.ts +49 -0
- package/dist/installer/lockfile.d.ts.map +1 -0
- package/dist/installer/lockfile.js +110 -0
- package/dist/installer/lockfile.js.map +1 -0
- package/dist/installer/registry.d.ts +84 -0
- package/dist/installer/registry.d.ts.map +1 -0
- package/dist/installer/registry.js +130 -0
- package/dist/installer/registry.js.map +1 -0
- package/dist/installer/semver.d.ts +38 -0
- package/dist/installer/semver.d.ts.map +1 -0
- package/dist/installer/semver.js +187 -0
- package/dist/installer/semver.js.map +1 -0
- package/dist/installer/spec.d.ts +30 -0
- package/dist/installer/spec.d.ts.map +1 -0
- package/dist/installer/spec.js +30 -0
- package/dist/installer/spec.js.map +1 -0
- package/dist/installer/tar.d.ts +17 -0
- package/dist/installer/tar.d.ts.map +1 -0
- package/dist/installer/tar.js +150 -0
- package/dist/installer/tar.js.map +1 -0
- package/dist/installer/tree.d.ts +48 -0
- package/dist/installer/tree.d.ts.map +1 -0
- package/dist/installer/tree.js +179 -0
- package/dist/installer/tree.js.map +1 -0
- package/dist/node/assert.d.ts +15 -0
- package/dist/node/assert.d.ts.map +1 -0
- package/dist/node/assert.js +137 -0
- package/dist/node/assert.js.map +1 -0
- package/dist/node/buffer.d.ts +84 -0
- package/dist/node/buffer.d.ts.map +1 -0
- package/dist/node/buffer.js +304 -0
- package/dist/node/buffer.js.map +1 -0
- package/dist/node/builtins.d.ts +25 -0
- package/dist/node/builtins.d.ts.map +1 -0
- package/dist/node/builtins.js +101 -0
- package/dist/node/builtins.js.map +1 -0
- package/dist/node/callable.d.ts +13 -0
- package/dist/node/callable.d.ts.map +1 -0
- package/dist/node/callable.js +26 -0
- package/dist/node/callable.js.map +1 -0
- package/dist/node/childProcess.d.ts +13 -0
- package/dist/node/childProcess.d.ts.map +1 -0
- package/dist/node/childProcess.js +143 -0
- package/dist/node/childProcess.js.map +1 -0
- package/dist/node/crypto.d.ts +3 -0
- package/dist/node/crypto.d.ts.map +1 -0
- package/dist/node/crypto.js +180 -0
- package/dist/node/crypto.js.map +1 -0
- package/dist/node/esm.d.ts +9 -0
- package/dist/node/esm.d.ts.map +1 -0
- package/dist/node/esm.js +202 -0
- package/dist/node/esm.js.map +1 -0
- package/dist/node/events.d.ts +40 -0
- package/dist/node/events.d.ts.map +1 -0
- package/dist/node/events.js +160 -0
- package/dist/node/events.js.map +1 -0
- package/dist/node/fs/index.d.ts +7 -0
- package/dist/node/fs/index.d.ts.map +1 -0
- package/dist/node/fs/index.js +270 -0
- package/dist/node/fs/index.js.map +1 -0
- package/dist/node/fs/stats.d.ts +93 -0
- package/dist/node/fs/stats.d.ts.map +1 -0
- package/dist/node/fs/stats.js +104 -0
- package/dist/node/fs/stats.js.map +1 -0
- package/dist/node/fs/sync.d.ts +98 -0
- package/dist/node/fs/sync.d.ts.map +1 -0
- package/dist/node/fs/sync.js +348 -0
- package/dist/node/fs/sync.js.map +1 -0
- package/dist/node/hashes.d.ts +15 -0
- package/dist/node/hashes.d.ts.map +1 -0
- package/dist/node/hashes.js +195 -0
- package/dist/node/hashes.js.map +1 -0
- package/dist/node/http/client.d.ts +35 -0
- package/dist/node/http/client.d.ts.map +1 -0
- package/dist/node/http/client.js +161 -0
- package/dist/node/http/client.js.map +1 -0
- package/dist/node/http/index.d.ts +5 -0
- package/dist/node/http/index.d.ts.map +1 -0
- package/dist/node/http/index.js +125 -0
- package/dist/node/http/index.js.map +1 -0
- package/dist/node/http/server.d.ts +135 -0
- package/dist/node/http/server.d.ts.map +1 -0
- package/dist/node/http/server.js +308 -0
- package/dist/node/http/server.js.map +1 -0
- package/dist/node/http/status.d.ts +3 -0
- package/dist/node/http/status.d.ts.map +1 -0
- package/dist/node/http/status.js +13 -0
- package/dist/node/http/status.js.map +1 -0
- package/dist/node/inspect.d.ts +22 -0
- package/dist/node/inspect.d.ts.map +1 -0
- package/dist/node/inspect.js +172 -0
- package/dist/node/inspect.js.map +1 -0
- package/dist/node/loader.d.ts +91 -0
- package/dist/node/loader.d.ts.map +1 -0
- package/dist/node/loader.js +265 -0
- package/dist/node/loader.js.map +1 -0
- package/dist/node/loop.d.ts +71 -0
- package/dist/node/loop.d.ts.map +1 -0
- package/dist/node/loop.js +189 -0
- package/dist/node/loop.js.map +1 -0
- package/dist/node/misc.d.ts +10 -0
- package/dist/node/misc.d.ts.map +1 -0
- package/dist/node/misc.js +256 -0
- package/dist/node/misc.js.map +1 -0
- package/dist/node/path.d.ts +14 -0
- package/dist/node/path.d.ts.map +1 -0
- package/dist/node/path.js +128 -0
- package/dist/node/path.js.map +1 -0
- package/dist/node/process.d.ts +31 -0
- package/dist/node/process.d.ts.map +1 -0
- package/dist/node/process.js +309 -0
- package/dist/node/process.js.map +1 -0
- package/dist/node/program.d.ts +19 -0
- package/dist/node/program.d.ts.map +1 -0
- package/dist/node/program.js +165 -0
- package/dist/node/program.js.map +1 -0
- package/dist/node/readline.d.ts +2 -0
- package/dist/node/readline.d.ts.map +1 -0
- package/dist/node/readline.js +155 -0
- package/dist/node/readline.js.map +1 -0
- package/dist/node/resolve.d.ts +45 -0
- package/dist/node/resolve.d.ts.map +1 -0
- package/dist/node/resolve.js +206 -0
- package/dist/node/resolve.js.map +1 -0
- package/dist/node/runtime.d.ts +40 -0
- package/dist/node/runtime.d.ts.map +1 -0
- package/dist/node/runtime.js +149 -0
- package/dist/node/runtime.js.map +1 -0
- package/dist/node/stream/index.d.ts +52 -0
- package/dist/node/stream/index.d.ts.map +1 -0
- package/dist/node/stream/index.js +184 -0
- package/dist/node/stream/index.js.map +1 -0
- package/dist/node/stream/readable.d.ts +83 -0
- package/dist/node/stream/readable.d.ts.map +1 -0
- package/dist/node/stream/readable.js +325 -0
- package/dist/node/stream/readable.js.map +1 -0
- package/dist/node/stream/writable.d.ts +80 -0
- package/dist/node/stream/writable.d.ts.map +1 -0
- package/dist/node/stream/writable.js +224 -0
- package/dist/node/stream/writable.js.map +1 -0
- package/dist/node/urlqs.d.ts +22 -0
- package/dist/node/urlqs.d.ts.map +1 -0
- package/dist/node/urlqs.js +165 -0
- package/dist/node/urlqs.js.map +1 -0
- package/dist/node/util.d.ts +37 -0
- package/dist/node/util.d.ts.map +1 -0
- package/dist/node/util.js +160 -0
- package/dist/node/util.js.map +1 -0
- package/dist/node/zlib.d.ts +2 -0
- package/dist/node/zlib.d.ts.map +1 -0
- package/dist/node/zlib.js +133 -0
- package/dist/node/zlib.js.map +1 -0
- package/dist/packageCdn.d.ts +40 -0
- package/dist/packageCdn.d.ts.map +1 -1
- package/dist/packageCdn.js +54 -7
- package/dist/packageCdn.js.map +1 -1
- package/dist/projectConfig.d.ts +6 -2
- package/dist/projectConfig.d.ts.map +1 -1
- package/dist/projectConfig.js +32 -8
- package/dist/projectConfig.js.map +1 -1
- package/dist/shell/builtins.d.ts +23 -0
- package/dist/shell/builtins.d.ts.map +1 -0
- package/dist/shell/builtins.js +131 -0
- package/dist/shell/builtins.js.map +1 -0
- package/dist/shell/context.d.ts +41 -0
- package/dist/shell/context.d.ts.map +1 -0
- package/dist/shell/context.js +65 -0
- package/dist/shell/context.js.map +1 -0
- package/dist/shell/devHandoff.d.ts +18 -0
- package/dist/shell/devHandoff.d.ts.map +1 -0
- package/dist/shell/devHandoff.js +36 -0
- package/dist/shell/devHandoff.js.map +1 -0
- package/dist/shell/exec.d.ts +67 -0
- package/dist/shell/exec.d.ts.map +1 -0
- package/dist/shell/exec.js +247 -0
- package/dist/shell/exec.js.map +1 -0
- package/dist/shell/expand.d.ts +28 -0
- package/dist/shell/expand.d.ts.map +1 -0
- package/dist/shell/expand.js +149 -0
- package/dist/shell/expand.js.map +1 -0
- package/dist/shell/fileCommands.d.ts +10 -0
- package/dist/shell/fileCommands.d.ts.map +1 -0
- package/dist/shell/fileCommands.js +208 -0
- package/dist/shell/fileCommands.js.map +1 -0
- package/dist/shell/lineEditor.d.ts +43 -0
- package/dist/shell/lineEditor.d.ts.map +1 -0
- package/dist/shell/lineEditor.js +234 -0
- package/dist/shell/lineEditor.js.map +1 -0
- package/dist/shell/npm.d.ts +6 -0
- package/dist/shell/npm.d.ts.map +1 -0
- package/dist/shell/npm.js +234 -0
- package/dist/shell/npm.js.map +1 -0
- package/dist/shell/parse.d.ts +73 -0
- package/dist/shell/parse.d.ts.map +1 -0
- package/dist/shell/parse.js +300 -0
- package/dist/shell/parse.js.map +1 -0
- package/dist/shell/program.d.ts +12 -0
- package/dist/shell/program.d.ts.map +1 -0
- package/dist/shell/program.js +219 -0
- package/dist/shell/program.js.map +1 -0
- package/dist/shell/textCommands.d.ts +15 -0
- package/dist/shell/textCommands.d.ts.map +1 -0
- package/dist/shell/textCommands.js +185 -0
- package/dist/shell/textCommands.js.map +1 -0
- package/dist/styleModules.d.ts +6 -0
- package/dist/styleModules.d.ts.map +1 -1
- package/dist/styleModules.js +14 -4
- package/dist/styleModules.js.map +1 -1
- package/dist/svelteCompiler.d.ts +28 -0
- package/dist/svelteCompiler.d.ts.map +1 -0
- package/dist/svelteCompiler.js +13 -0
- package/dist/svelteCompiler.js.map +1 -0
- package/dist/system/commands.d.ts +26 -0
- package/dist/system/commands.d.ts.map +1 -0
- package/dist/system/commands.js +53 -0
- package/dist/system/commands.js.map +1 -0
- package/dist/system/index.d.ts +23 -0
- package/dist/system/index.d.ts.map +1 -0
- package/dist/system/index.js +16 -0
- package/dist/system/index.js.map +1 -0
- package/dist/system/kernel.d.ts +54 -0
- package/dist/system/kernel.d.ts.map +1 -0
- package/dist/system/kernel.js +81 -0
- package/dist/system/kernel.js.map +1 -0
- package/dist/system/ports.d.ts +32 -0
- package/dist/system/ports.d.ts.map +1 -0
- package/dist/system/ports.js +57 -0
- package/dist/system/ports.js.map +1 -0
- package/dist/system/process.d.ts +32 -0
- package/dist/system/process.d.ts.map +1 -0
- package/dist/system/process.js +130 -0
- package/dist/system/process.js.map +1 -0
- package/dist/system/programs.d.ts +10 -0
- package/dist/system/programs.d.ts.map +1 -0
- package/dist/system/programs.js +22 -0
- package/dist/system/programs.js.map +1 -0
- package/dist/system/terminal.d.ts +45 -0
- package/dist/system/terminal.d.ts.map +1 -0
- package/dist/system/terminal.js +127 -0
- package/dist/system/terminal.js.map +1 -0
- package/dist/system/types.d.ts +100 -0
- package/dist/system/types.d.ts.map +1 -0
- package/dist/system/types.js +2 -0
- package/dist/system/types.js.map +1 -0
- package/dist/vfs.d.ts +28 -4
- package/dist/vfs.d.ts.map +1 -1
- package/dist/vfs.js +95 -32
- package/dist/vfs.js.map +1 -1
- package/dist/vueCompiler.d.ts +75 -0
- package/dist/vueCompiler.d.ts.map +1 -0
- package/dist/vueCompiler.js +67 -0
- package/dist/vueCompiler.js.map +1 -0
- package/package.json +18 -2
- package/src/build.ts +105 -0
- package/src/buildHost.ts +154 -0
- package/src/buildHtml.ts +101 -0
- package/src/bundler.ts +190 -0
- package/src/check/acquire.ts +212 -0
- package/src/check/compilerHost.ts +138 -0
- package/src/check/diagnostics.ts +48 -0
- package/src/check/index.ts +28 -0
- package/src/check/projects.ts +149 -0
- package/src/check/shims.ts +88 -0
- package/src/check/typeStore.ts +103 -0
- package/src/check/typecheck.ts +134 -0
- package/src/compileComponent.ts +21 -0
- package/src/compileScript.ts +42 -13
- package/src/components.ts +59 -0
- package/src/detectProject.ts +18 -6
- package/src/devServer.ts +16 -11
- package/src/hash.ts +22 -0
- package/src/index.ts +35 -6
- package/src/installer/bins.ts +64 -0
- package/src/installer/index.ts +13 -0
- package/src/installer/install.ts +275 -0
- package/src/installer/lockfile.ts +146 -0
- package/src/installer/registry.ts +175 -0
- package/src/installer/semver.ts +190 -0
- package/src/installer/spec.ts +53 -0
- package/src/installer/tar.ts +155 -0
- package/src/installer/tree.ts +236 -0
- package/src/node/assert.ts +127 -0
- package/src/node/buffer.ts +304 -0
- package/src/node/builtins.ts +123 -0
- package/src/node/callable.ts +25 -0
- package/src/node/childProcess.ts +164 -0
- package/src/node/crypto.ts +187 -0
- package/src/node/esm.ts +196 -0
- package/src/node/events.ts +176 -0
- package/src/node/fs/index.ts +277 -0
- package/src/node/fs/stats.ts +110 -0
- package/src/node/fs/sync.ts +335 -0
- package/src/node/hashes.ts +171 -0
- package/src/node/http/client.ts +173 -0
- package/src/node/http/index.ts +122 -0
- package/src/node/http/server.ts +308 -0
- package/src/node/http/status.ts +13 -0
- package/src/node/inspect.ts +166 -0
- package/src/node/loader.ts +293 -0
- package/src/node/loop.ts +193 -0
- package/src/node/misc.ts +250 -0
- package/src/node/path.ts +135 -0
- package/src/node/process.ts +324 -0
- package/src/node/program.ts +170 -0
- package/src/node/readline.ts +157 -0
- package/src/node/resolve.ts +216 -0
- package/src/node/runtime.ts +184 -0
- package/src/node/stream/index.ts +196 -0
- package/src/node/stream/readable.ts +345 -0
- package/src/node/stream/writable.ts +244 -0
- package/src/node/urlqs.ts +162 -0
- package/src/node/util.ts +145 -0
- package/src/node/zlib.ts +145 -0
- package/src/packageCdn.ts +91 -7
- package/src/projectConfig.ts +34 -7
- package/src/shell/builtins.ts +141 -0
- package/src/shell/context.ts +89 -0
- package/src/shell/devHandoff.ts +49 -0
- package/src/shell/exec.ts +268 -0
- package/src/shell/expand.ts +145 -0
- package/src/shell/fileCommands.ts +206 -0
- package/src/shell/lineEditor.ts +233 -0
- package/src/shell/npm.ts +229 -0
- package/src/shell/parse.ts +295 -0
- package/src/shell/program.ts +223 -0
- package/src/shell/textCommands.ts +177 -0
- package/src/styleModules.ts +15 -4
- package/src/svelteCompiler.ts +31 -0
- package/src/system/commands.ts +72 -0
- package/src/system/index.ts +22 -0
- package/src/system/kernel.ts +106 -0
- package/src/system/ports.ts +73 -0
- package/src/system/process.ts +158 -0
- package/src/system/programs.ts +31 -0
- package/src/system/terminal.ts +135 -0
- package/src/system/types.ts +103 -0
- package/src/vfs.ts +92 -28
- package/src/vueCompiler.ts +121 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `url` (WHATWG URL plus the legacy `parse`/`format`/`resolve`) and
|
|
3
|
+
* `querystring`. Legacy `url.parse` is still everywhere in Express-era code
|
|
4
|
+
* (`parseurl`, `send`), so it returns Node's full shape.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function createQuerystringModule(): Record<string, unknown> {
|
|
8
|
+
const escape = (s: string) => encodeURIComponent(s);
|
|
9
|
+
const unescape = (s: string) => {
|
|
10
|
+
try {
|
|
11
|
+
return decodeURIComponent(s);
|
|
12
|
+
} catch {
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const stringifyPrimitive = (v: unknown) => (typeof v === 'string' ? v : typeof v === 'number' && Number.isFinite(v) ? String(v) : typeof v === 'boolean' || typeof v === 'bigint' ? String(v) : '');
|
|
17
|
+
const parse = (str: string, sep = '&', eq = '=', options?: { maxKeys?: number; decodeURIComponent?: (s: string) => string }) => {
|
|
18
|
+
const out: Record<string, string | string[]> = Object.create(null);
|
|
19
|
+
if (typeof str !== 'string' || !str) return out;
|
|
20
|
+
const decode = options?.decodeURIComponent ?? unescape;
|
|
21
|
+
const parts = str.split(sep);
|
|
22
|
+
const max = options?.maxKeys ?? 1000;
|
|
23
|
+
for (const part of max > 0 ? parts.slice(0, max) : parts) {
|
|
24
|
+
if (!part) continue;
|
|
25
|
+
const idx = part.indexOf(eq);
|
|
26
|
+
const key = decode((idx >= 0 ? part.slice(0, idx) : part).replace(/\+/g, ' '));
|
|
27
|
+
const value = idx >= 0 ? decode(part.slice(idx + eq.length).replace(/\+/g, ' ')) : '';
|
|
28
|
+
const existing = out[key];
|
|
29
|
+
if (existing === undefined) out[key] = value;
|
|
30
|
+
else if (Array.isArray(existing)) existing.push(value);
|
|
31
|
+
else out[key] = [existing, value];
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
};
|
|
35
|
+
const stringify = (obj: Record<string, unknown>, sep = '&', eq = '=', options?: { encodeURIComponent?: (s: string) => string }) => {
|
|
36
|
+
const encode = options?.encodeURIComponent ?? escape;
|
|
37
|
+
if (!obj || typeof obj !== 'object') return '';
|
|
38
|
+
return Object.keys(obj)
|
|
39
|
+
.map((k) => {
|
|
40
|
+
const v = obj[k];
|
|
41
|
+
const ks = encode(stringifyPrimitive(k)) + eq;
|
|
42
|
+
return Array.isArray(v) ? v.map((x) => ks + encode(stringifyPrimitive(x))).join(sep) : ks + encode(stringifyPrimitive(v));
|
|
43
|
+
})
|
|
44
|
+
.filter(Boolean)
|
|
45
|
+
.join(sep);
|
|
46
|
+
};
|
|
47
|
+
return { parse, decode: parse, stringify, encode: stringify, escape, unescape };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface LegacyUrl {
|
|
51
|
+
protocol: string | null;
|
|
52
|
+
slashes: boolean | null;
|
|
53
|
+
auth: string | null;
|
|
54
|
+
host: string | null;
|
|
55
|
+
port: string | null;
|
|
56
|
+
hostname: string | null;
|
|
57
|
+
hash: string | null;
|
|
58
|
+
search: string | null;
|
|
59
|
+
query: string | Record<string, unknown> | null;
|
|
60
|
+
pathname: string | null;
|
|
61
|
+
path: string | null;
|
|
62
|
+
href: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function createUrlModule(qs: Record<string, any>): Record<string, unknown> {
|
|
66
|
+
function parse(input: string, parseQueryString = false, slashesDenoteHost = false): LegacyUrl {
|
|
67
|
+
let rest = input.trim();
|
|
68
|
+
const out: LegacyUrl = { protocol: null, slashes: null, auth: null, host: null, port: null, hostname: null, hash: null, search: null, query: null, pathname: null, path: null, href: '' };
|
|
69
|
+
const hashAt = rest.indexOf('#');
|
|
70
|
+
if (hashAt >= 0) {
|
|
71
|
+
out.hash = rest.slice(hashAt);
|
|
72
|
+
rest = rest.slice(0, hashAt);
|
|
73
|
+
}
|
|
74
|
+
const queryAt = rest.indexOf('?');
|
|
75
|
+
if (queryAt >= 0) {
|
|
76
|
+
out.search = rest.slice(queryAt);
|
|
77
|
+
out.query = rest.slice(queryAt + 1);
|
|
78
|
+
rest = rest.slice(0, queryAt);
|
|
79
|
+
} else if (parseQueryString) {
|
|
80
|
+
out.search = '';
|
|
81
|
+
out.query = {};
|
|
82
|
+
}
|
|
83
|
+
const proto = /^([a-z][a-z0-9.+-]*:)/i.exec(rest);
|
|
84
|
+
if (proto) {
|
|
85
|
+
out.protocol = proto[1]!.toLowerCase();
|
|
86
|
+
rest = rest.slice(proto[1]!.length);
|
|
87
|
+
}
|
|
88
|
+
if ((proto || slashesDenoteHost) && rest.startsWith('//')) {
|
|
89
|
+
out.slashes = true;
|
|
90
|
+
rest = rest.slice(2);
|
|
91
|
+
const end = rest.search(/[/]/);
|
|
92
|
+
let authority = end >= 0 ? rest.slice(0, end) : rest;
|
|
93
|
+
rest = end >= 0 ? rest.slice(end) : '';
|
|
94
|
+
const at = authority.lastIndexOf('@');
|
|
95
|
+
if (at >= 0) {
|
|
96
|
+
out.auth = decodeURIComponent(authority.slice(0, at));
|
|
97
|
+
authority = authority.slice(at + 1);
|
|
98
|
+
}
|
|
99
|
+
out.host = authority.toLowerCase();
|
|
100
|
+
const portMatch = /:(\d*)$/.exec(out.host);
|
|
101
|
+
if (portMatch) {
|
|
102
|
+
out.port = portMatch[1] || null;
|
|
103
|
+
out.hostname = out.host.slice(0, -portMatch[0].length);
|
|
104
|
+
} else out.hostname = out.host;
|
|
105
|
+
if (out.hostname.startsWith('[') && out.hostname.endsWith(']')) out.hostname = out.hostname.slice(1, -1);
|
|
106
|
+
if (!rest && out.protocol && /^(https?|ftp|wss?|file):$/.test(out.protocol)) rest = '/';
|
|
107
|
+
}
|
|
108
|
+
out.pathname = rest || (out.slashes ? '/' : null);
|
|
109
|
+
if (parseQueryString && typeof out.query === 'string') out.query = qs.parse(out.query);
|
|
110
|
+
out.path = (out.pathname ?? '') + (out.search ?? '') || null;
|
|
111
|
+
out.href = format(out);
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function format(obj: Partial<LegacyUrl> | URL | string): string {
|
|
116
|
+
if (typeof obj === 'string') return format(parse(obj));
|
|
117
|
+
if (obj instanceof URL) return obj.href;
|
|
118
|
+
const protocol = obj.protocol ? (obj.protocol.endsWith(':') ? obj.protocol : obj.protocol + ':') : '';
|
|
119
|
+
let host = '';
|
|
120
|
+
if (obj.host) host = (obj.auth ? encodeURIComponent(obj.auth).replace(/%3A/i, ':') + '@' : '') + obj.host;
|
|
121
|
+
else if (obj.hostname) host = (obj.auth ? obj.auth + '@' : '') + (obj.hostname.includes(':') ? `[${obj.hostname}]` : obj.hostname) + (obj.port ? ':' + obj.port : '');
|
|
122
|
+
let search = obj.search ?? '';
|
|
123
|
+
if (!search && obj.query && typeof obj.query === 'object') {
|
|
124
|
+
const s = qs.stringify(obj.query);
|
|
125
|
+
if (s) search = '?' + s;
|
|
126
|
+
} else if (search && !search.startsWith('?')) search = '?' + search;
|
|
127
|
+
const slashes = obj.slashes || (host && /^(https?|ftp|wss?|file):$/.test(protocol)) ? '//' : '';
|
|
128
|
+
let pathname = obj.pathname ?? '';
|
|
129
|
+
if (host && pathname && !pathname.startsWith('/')) pathname = '/' + pathname;
|
|
130
|
+
const hash = obj.hash ? (obj.hash.startsWith('#') ? obj.hash : '#' + obj.hash) : '';
|
|
131
|
+
return `${protocol}${slashes}${host}${pathname}${search}${hash}`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function resolve(from: string, to: string): string {
|
|
135
|
+
const base = new URL(from, 'resolve://');
|
|
136
|
+
const resolved = new URL(to, base);
|
|
137
|
+
if (resolved.protocol === 'resolve:') {
|
|
138
|
+
const { pathname, search, hash } = resolved;
|
|
139
|
+
return pathname + search + hash;
|
|
140
|
+
}
|
|
141
|
+
return resolved.href;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
URL,
|
|
146
|
+
URLSearchParams,
|
|
147
|
+
parse,
|
|
148
|
+
format,
|
|
149
|
+
resolve,
|
|
150
|
+
resolveObject: (from: string, to: string) => parse(resolve(from, to)),
|
|
151
|
+
fileURLToPath: (url: string | URL) => {
|
|
152
|
+
const u = typeof url === 'string' ? new URL(url) : url;
|
|
153
|
+
if (u.protocol !== 'file:') throw Object.assign(new TypeError('The URL must be of scheme file'), { code: 'ERR_INVALID_URL_SCHEME' });
|
|
154
|
+
return decodeURIComponent(u.pathname);
|
|
155
|
+
},
|
|
156
|
+
pathToFileURL: (path: string) => new URL('file://' + encodeURI(path).replace(/[?#]/g, encodeURIComponent)),
|
|
157
|
+
domainToASCII: (d: string) => d,
|
|
158
|
+
domainToUnicode: (d: string) => d,
|
|
159
|
+
urlToHttpOptions: (u: URL) => ({ protocol: u.protocol, hostname: u.hostname, hash: u.hash, search: u.search, pathname: u.pathname, path: u.pathname + u.search, href: u.href, port: u.port ? Number(u.port) : undefined }),
|
|
160
|
+
Url: function Url() {},
|
|
161
|
+
};
|
|
162
|
+
}
|
package/src/node/util.ts
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node's `util` module: formatting and inspection (inspect.ts), the classic
|
|
3
|
+
* helpers (`inherits`, `promisify`, `deprecate`, `callbackify`), `types` and
|
|
4
|
+
* `isDeepStrictEqual`.
|
|
5
|
+
*/
|
|
6
|
+
import { format, inspect } from './inspect.js';
|
|
7
|
+
|
|
8
|
+
export const promisifyCustom = Symbol.for('nodejs.util.promisify.custom');
|
|
9
|
+
|
|
10
|
+
export function promisify(fn: (...args: any[]) => unknown): (...args: any[]) => Promise<any> {
|
|
11
|
+
if (typeof fn !== 'function') throw new TypeError('The "original" argument must be of type function');
|
|
12
|
+
const custom = (fn as any)[promisifyCustom];
|
|
13
|
+
if (typeof custom === 'function') return custom;
|
|
14
|
+
function promisified(this: unknown, ...args: unknown[]) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
fn.call(this, ...args, (error: unknown, ...values: unknown[]) => {
|
|
17
|
+
if (error) reject(error);
|
|
18
|
+
else resolve(values.length > 1 ? values : values[0]);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
Object.setPrototypeOf(promisified, Object.getPrototypeOf(fn));
|
|
23
|
+
return Object.defineProperties(promisified, Object.getOwnPropertyDescriptors(fn));
|
|
24
|
+
}
|
|
25
|
+
promisify.custom = promisifyCustom;
|
|
26
|
+
|
|
27
|
+
export function inherits(ctor: { prototype: object; super_?: unknown }, superCtor: { prototype: object }): void {
|
|
28
|
+
if (!superCtor?.prototype) throw new TypeError('The "superCtor.prototype" property must be of type object');
|
|
29
|
+
ctor.super_ = superCtor;
|
|
30
|
+
Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function isDeepStrictEqual(a: unknown, b: unknown, seen = new Map<object, object>()): boolean {
|
|
34
|
+
if (Object.is(a, b)) return true;
|
|
35
|
+
if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;
|
|
36
|
+
if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;
|
|
37
|
+
if (seen.get(a) === b) return true;
|
|
38
|
+
seen.set(a, b);
|
|
39
|
+
if (a instanceof Date) return a.getTime() === (b as Date).getTime();
|
|
40
|
+
if (a instanceof RegExp) return String(a) === String(b);
|
|
41
|
+
if (a instanceof Map) {
|
|
42
|
+
const m = b as Map<unknown, unknown>;
|
|
43
|
+
if (a.size !== m.size) return false;
|
|
44
|
+
for (const [k, v] of a) if (!m.has(k) || !isDeepStrictEqual(v, m.get(k), seen)) return false;
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (a instanceof Set) {
|
|
48
|
+
const s = b as Set<unknown>;
|
|
49
|
+
if (a.size !== s.size) return false;
|
|
50
|
+
for (const v of a) if (!s.has(v) && ![...s].some((w) => isDeepStrictEqual(v, w, seen))) return false;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (ArrayBuffer.isView(a)) {
|
|
54
|
+
const x = a as unknown as ArrayLike<number>;
|
|
55
|
+
const y = b as unknown as ArrayLike<number>;
|
|
56
|
+
if (x.length !== y.length) return false;
|
|
57
|
+
for (let i = 0; i < x.length; i++) if (!Object.is(x[i], y[i])) return false;
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
const ka = Object.keys(a);
|
|
61
|
+
const kb = Object.keys(b);
|
|
62
|
+
if (ka.length !== kb.length) return false;
|
|
63
|
+
return ka.every((k) => Object.prototype.hasOwnProperty.call(b, k) && isDeepStrictEqual((a as any)[k], (b as any)[k], seen));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const tag = (v: unknown) => Object.prototype.toString.call(v).slice(8, -1);
|
|
67
|
+
|
|
68
|
+
export const types = {
|
|
69
|
+
isPromise: (v: unknown) => v instanceof Promise,
|
|
70
|
+
isDate: (v: unknown) => v instanceof Date,
|
|
71
|
+
isRegExp: (v: unknown) => v instanceof RegExp,
|
|
72
|
+
isMap: (v: unknown) => v instanceof Map,
|
|
73
|
+
isSet: (v: unknown) => v instanceof Set,
|
|
74
|
+
isWeakMap: (v: unknown) => v instanceof WeakMap,
|
|
75
|
+
isWeakSet: (v: unknown) => v instanceof WeakSet,
|
|
76
|
+
isNativeError: (v: unknown) => v instanceof Error,
|
|
77
|
+
isTypedArray: (v: unknown) => ArrayBuffer.isView(v) && !(v instanceof DataView),
|
|
78
|
+
isUint8Array: (v: unknown) => v instanceof Uint8Array,
|
|
79
|
+
isArrayBuffer: (v: unknown) => v instanceof ArrayBuffer,
|
|
80
|
+
isAnyArrayBuffer: (v: unknown) => v instanceof ArrayBuffer || tag(v) === 'SharedArrayBuffer',
|
|
81
|
+
isArrayBufferView: (v: unknown) => ArrayBuffer.isView(v),
|
|
82
|
+
isDataView: (v: unknown) => v instanceof DataView,
|
|
83
|
+
isAsyncFunction: (v: unknown) => tag(v) === 'AsyncFunction' || tag(v) === 'AsyncGeneratorFunction',
|
|
84
|
+
isGeneratorFunction: (v: unknown) => tag(v) === 'GeneratorFunction' || tag(v) === 'AsyncGeneratorFunction',
|
|
85
|
+
isGeneratorObject: (v: unknown) => tag(v) === 'Generator',
|
|
86
|
+
isBoxedPrimitive: (v: unknown) => v instanceof Number || v instanceof String || v instanceof Boolean,
|
|
87
|
+
isProxy: () => false,
|
|
88
|
+
isExternal: () => false,
|
|
89
|
+
isModuleNamespaceObject: (v: unknown) => tag(v) === 'Module',
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export function createUtilModule(env: () => Record<string, string | undefined>, warn: (message: string) => void): Record<string, unknown> {
|
|
93
|
+
const warned = new Set<string>();
|
|
94
|
+
return {
|
|
95
|
+
format,
|
|
96
|
+
formatWithOptions: (_options: unknown, ...args: unknown[]) => format(...args),
|
|
97
|
+
inspect,
|
|
98
|
+
inherits,
|
|
99
|
+
promisify,
|
|
100
|
+
callbackify(fn: (...args: any[]) => Promise<unknown>) {
|
|
101
|
+
return function (this: unknown, ...args: any[]) {
|
|
102
|
+
const callback = args.pop() as (error: unknown, value?: unknown) => void;
|
|
103
|
+
fn.apply(this, args).then((value) => callback(null, value), (error) => callback(error ?? new Error('Promise was rejected with a falsy value')));
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
deprecate<T extends (...args: any[]) => unknown>(fn: T, message: string, code?: string): T {
|
|
107
|
+
return function (this: unknown, ...args: unknown[]) {
|
|
108
|
+
const key = code ?? message;
|
|
109
|
+
if (!warned.has(key)) {
|
|
110
|
+
warned.add(key);
|
|
111
|
+
warn(`(node) [${code ?? 'DEP'}] DeprecationWarning: ${message}`);
|
|
112
|
+
}
|
|
113
|
+
return fn.apply(this, args);
|
|
114
|
+
} as T;
|
|
115
|
+
},
|
|
116
|
+
debuglog(section: string) {
|
|
117
|
+
const enabled = new RegExp(`\\b${section}\\b`, 'i').test(env().NODE_DEBUG ?? '');
|
|
118
|
+
const log = (...args: unknown[]) => enabled && warn(`${section.toUpperCase()}: ${format(...args)}`);
|
|
119
|
+
log.enabled = enabled;
|
|
120
|
+
return log;
|
|
121
|
+
},
|
|
122
|
+
isDeepStrictEqual: (a: unknown, b: unknown) => isDeepStrictEqual(a, b),
|
|
123
|
+
types,
|
|
124
|
+
TextEncoder,
|
|
125
|
+
TextDecoder,
|
|
126
|
+
stripVTControlCharacters: (s: string) => s.replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, ''),
|
|
127
|
+
styleText: (_style: unknown, text: string) => text,
|
|
128
|
+
toUSVString: (s: string) => s.replace(/[\uD800-\uDFFF]/g, '�'),
|
|
129
|
+
isArray: Array.isArray,
|
|
130
|
+
isBoolean: (v: unknown) => typeof v === 'boolean',
|
|
131
|
+
isNull: (v: unknown) => v === null,
|
|
132
|
+
isNullOrUndefined: (v: unknown) => v == null,
|
|
133
|
+
isNumber: (v: unknown) => typeof v === 'number',
|
|
134
|
+
isString: (v: unknown) => typeof v === 'string',
|
|
135
|
+
isSymbol: (v: unknown) => typeof v === 'symbol',
|
|
136
|
+
isUndefined: (v: unknown) => v === undefined,
|
|
137
|
+
isRegExp: types.isRegExp,
|
|
138
|
+
isObject: (v: unknown) => v !== null && typeof v === 'object',
|
|
139
|
+
isDate: types.isDate,
|
|
140
|
+
isError: types.isNativeError,
|
|
141
|
+
isFunction: (v: unknown) => typeof v === 'function',
|
|
142
|
+
isPrimitive: (v: unknown) => v === null || (typeof v !== 'object' && typeof v !== 'function'),
|
|
143
|
+
isBuffer: (v: unknown) => (v as { constructor?: { name?: string } })?.constructor?.name === 'Buffer',
|
|
144
|
+
};
|
|
145
|
+
}
|
package/src/node/zlib.ts
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `zlib` over fflate: gzip/deflate/raw deflate in sync, callback, promise-less
|
|
3
|
+
* and streaming forms (compression middleware pipes through `createGzip`).
|
|
4
|
+
* Brotli is not available and says so.
|
|
5
|
+
*/
|
|
6
|
+
import * as fflate from 'fflate';
|
|
7
|
+
import { Buffer } from './buffer.js';
|
|
8
|
+
import { Transform } from './stream/index.js';
|
|
9
|
+
|
|
10
|
+
type Input = string | ArrayBufferView | ArrayBuffer;
|
|
11
|
+
type Options = { level?: number };
|
|
12
|
+
|
|
13
|
+
const bytes = (input: Input): Uint8Array =>
|
|
14
|
+
typeof input === 'string' ? Buffer.from(input) : input instanceof ArrayBuffer ? new Uint8Array(input) : new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
15
|
+
|
|
16
|
+
const level = (options?: Options) => (options?.level === undefined || options.level < 0 ? 6 : Math.min(9, options.level)) as fflate.DeflateOptions['level'];
|
|
17
|
+
|
|
18
|
+
const SYNC: Record<string, (data: Uint8Array, options?: Options) => Uint8Array> = {
|
|
19
|
+
gzip: (d, o) => fflate.gzipSync(d, { level: level(o) }),
|
|
20
|
+
gunzip: (d) => fflate.gunzipSync(d),
|
|
21
|
+
deflate: (d, o) => fflate.zlibSync(d, { level: level(o) }),
|
|
22
|
+
inflate: (d) => fflate.unzlibSync(d),
|
|
23
|
+
deflateRaw: (d, o) => fflate.deflateSync(d, { level: level(o) }),
|
|
24
|
+
inflateRaw: (d) => fflate.inflateSync(d),
|
|
25
|
+
unzip: (d) => fflate.decompressSync(d),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type StreamCtor = new (cb?: fflate.FlateStreamHandler) => { push(chunk: Uint8Array, final?: boolean): void; ondata: fflate.FlateStreamHandler };
|
|
29
|
+
const STREAMS: Record<string, (options?: Options) => InstanceType<StreamCtor>> = {
|
|
30
|
+
Gzip: (o) => new fflate.Gzip({ level: level(o) }),
|
|
31
|
+
Gunzip: () => new fflate.Gunzip(),
|
|
32
|
+
Deflate: (o) => new fflate.Zlib({ level: level(o) }),
|
|
33
|
+
Inflate: () => new fflate.Unzlib(),
|
|
34
|
+
DeflateRaw: (o) => new fflate.Deflate({ level: level(o) }),
|
|
35
|
+
InflateRaw: () => new fflate.Inflate(),
|
|
36
|
+
Unzip: () => new fflate.Decompress() as unknown as InstanceType<StreamCtor>,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function zlibError(error: unknown): Error {
|
|
40
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
41
|
+
return Object.assign(new Error(message || 'invalid compressed data'), { code: 'Z_DATA_ERROR', errno: -3 });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
class ZlibStream extends Transform {
|
|
45
|
+
private readonly engine: InstanceType<StreamCtor>;
|
|
46
|
+
bytesWritten = 0;
|
|
47
|
+
|
|
48
|
+
constructor(kind: string, options?: Options) {
|
|
49
|
+
super();
|
|
50
|
+
this.engine = STREAMS[kind]!(options);
|
|
51
|
+
this.engine.ondata = (data: Uint8Array) => {
|
|
52
|
+
if (data.length) this.push(Buffer.from(data));
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override _transform(chunk: Uint8Array, _encoding: string, callback: (error?: Error | null) => void): void {
|
|
57
|
+
try {
|
|
58
|
+
this.bytesWritten += chunk.length;
|
|
59
|
+
this.engine.push(chunk, false);
|
|
60
|
+
callback();
|
|
61
|
+
} catch (error) {
|
|
62
|
+
callback(zlibError(error));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
override _flush(callback: (error?: Error | null) => void): void {
|
|
67
|
+
try {
|
|
68
|
+
this.engine.push(new Uint8Array(0), true);
|
|
69
|
+
callback();
|
|
70
|
+
} catch (error) {
|
|
71
|
+
callback(zlibError(error));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
flush(_kind?: unknown, callback?: () => void): void {
|
|
76
|
+
callback?.();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
params(_level: number, _strategy: number, callback?: () => void): void {
|
|
80
|
+
callback?.();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
close(callback?: () => void): void {
|
|
84
|
+
this.destroy();
|
|
85
|
+
callback?.();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const noBrotli = () => {
|
|
90
|
+
throw Object.assign(new Error('Brotli is not available in the browser runtime'), { code: 'ERR_FEATURE_UNAVAILABLE_ON_PLATFORM' });
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export function createZlibModule(): Record<string, unknown> {
|
|
94
|
+
const mod: Record<string, unknown> = {
|
|
95
|
+
constants: {
|
|
96
|
+
Z_NO_FLUSH: 0, Z_PARTIAL_FLUSH: 1, Z_SYNC_FLUSH: 2, Z_FULL_FLUSH: 3, Z_FINISH: 4, Z_BLOCK: 5,
|
|
97
|
+
Z_OK: 0, Z_STREAM_END: 1, Z_NEED_DICT: 2, Z_ERRNO: -1, Z_STREAM_ERROR: -2, Z_DATA_ERROR: -3, Z_BUF_ERROR: -5,
|
|
98
|
+
Z_NO_COMPRESSION: 0, Z_BEST_SPEED: 1, Z_BEST_COMPRESSION: 9, Z_DEFAULT_COMPRESSION: -1,
|
|
99
|
+
Z_FILTERED: 1, Z_HUFFMAN_ONLY: 2, Z_RLE: 3, Z_FIXED: 4, Z_DEFAULT_STRATEGY: 0,
|
|
100
|
+
BROTLI_OPERATION_PROCESS: 0, BROTLI_OPERATION_FLUSH: 1, BROTLI_OPERATION_FINISH: 2, BROTLI_PARAM_QUALITY: 1,
|
|
101
|
+
},
|
|
102
|
+
brotliCompressSync: noBrotli,
|
|
103
|
+
brotliDecompressSync: noBrotli,
|
|
104
|
+
brotliCompress: noBrotli,
|
|
105
|
+
brotliDecompress: noBrotli,
|
|
106
|
+
createBrotliCompress: noBrotli,
|
|
107
|
+
createBrotliDecompress: noBrotli,
|
|
108
|
+
crc32: (data: Input, value = 0) => {
|
|
109
|
+
let crc = ~value >>> 0;
|
|
110
|
+
for (const byte of bytes(data)) {
|
|
111
|
+
crc ^= byte;
|
|
112
|
+
for (let k = 0; k < 8; k++) crc = crc & 1 ? (crc >>> 1) ^ 0xedb88320 : crc >>> 1;
|
|
113
|
+
}
|
|
114
|
+
return ~crc >>> 0;
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
for (const [name, fn] of Object.entries(SYNC)) {
|
|
118
|
+
mod[`${name}Sync`] = (input: Input, options?: Options) => {
|
|
119
|
+
try {
|
|
120
|
+
return Buffer.from(fn(bytes(input), options));
|
|
121
|
+
} catch (error) {
|
|
122
|
+
throw zlibError(error);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
mod[name] = (input: Input, options: Options | ((e: Error | null, r?: Buffer) => void), callback?: (e: Error | null, r?: Buffer) => void) => {
|
|
126
|
+
const cb = (typeof options === 'function' ? options : callback)!;
|
|
127
|
+
queueMicrotask(() => {
|
|
128
|
+
try {
|
|
129
|
+
cb(null, Buffer.from(fn(bytes(input), typeof options === 'object' ? options : undefined)));
|
|
130
|
+
} catch (error) {
|
|
131
|
+
cb(zlibError(error));
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
for (const kind of Object.keys(STREAMS)) {
|
|
137
|
+
mod[`create${kind}`] = (options?: Options) => new ZlibStream(kind, options);
|
|
138
|
+
mod[kind] = class extends ZlibStream {
|
|
139
|
+
constructor(options?: Options) {
|
|
140
|
+
super(kind, options);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return mod;
|
|
145
|
+
}
|
package/src/packageCdn.ts
CHANGED
|
@@ -8,6 +8,28 @@ export interface PackageCdn {
|
|
|
8
8
|
urlFor(name: string, subpath: string): string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Makes the CDN for one project, from its dependency ranges. `dev` is true for the
|
|
13
|
+
* dev server and false for a production build, so a factory can pick development
|
|
14
|
+
* or production package builds (React's readable errors vs its small bundle).
|
|
15
|
+
* It may be async: the esm.sh one loads package metadata first.
|
|
16
|
+
*/
|
|
17
|
+
export type PackageCdnFactory = (
|
|
18
|
+
dependencies: Record<string, string>,
|
|
19
|
+
options: { dev: boolean },
|
|
20
|
+
) => PackageCdn | Promise<PackageCdn>;
|
|
21
|
+
|
|
22
|
+
/** The package.json fields that say which other packages a package imports. */
|
|
23
|
+
export interface PackageDependencyFields {
|
|
24
|
+
dependencies?: Record<string, string>;
|
|
25
|
+
peerDependencies?: Record<string, string>;
|
|
26
|
+
optionalDependencies?: Record<string, string>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** esm.sh, pinned to the project's ranges, with each declared package's manifest loaded. */
|
|
30
|
+
export const esmShCdnFactory: PackageCdnFactory = async (dependencies, { dev }) =>
|
|
31
|
+
createEsmShCdn({ dependencies, dev, manifests: await loadPackageManifests(dependencies) });
|
|
32
|
+
|
|
11
33
|
export interface EsmShOptions {
|
|
12
34
|
/** Defaults to https://esm.sh. Any esm.sh-compatible server works. */
|
|
13
35
|
origin?: string;
|
|
@@ -15,34 +37,96 @@ export interface EsmShOptions {
|
|
|
15
37
|
dependencies?: Record<string, string>;
|
|
16
38
|
/** Serve development builds (readable React errors). Default true. */
|
|
17
39
|
dev?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Each declared package's own dependency fields, by name. They decide which pins
|
|
42
|
+
* go on that package's URL (see `urlFor`). A declared package missing here falls
|
|
43
|
+
* back to carrying every other pin.
|
|
44
|
+
*/
|
|
45
|
+
manifests?: Record<string, PackageDependencyFields>;
|
|
18
46
|
}
|
|
19
47
|
|
|
20
48
|
/** A range the CDN can't fetch (`workspace:*`, `file:../x`, `link:`, git URLs). */
|
|
21
|
-
function isRegistryRange(range: string): boolean {
|
|
49
|
+
export function isRegistryRange(range: string): boolean {
|
|
22
50
|
return !/^(workspace|file|link|portal|git\+|git:|github:|https?:)/.test(range) && !range.includes('/');
|
|
23
51
|
}
|
|
24
52
|
|
|
53
|
+
function importsPackage(manifest: PackageDependencyFields, name: string): boolean {
|
|
54
|
+
return [manifest.dependencies, manifest.peerDependencies, manifest.optionalDependencies].some((field) => !!field && name in field);
|
|
55
|
+
}
|
|
56
|
+
|
|
25
57
|
export function createEsmShCdn(options: EsmShOptions = {}): PackageCdn {
|
|
26
58
|
const origin = (options.origin ?? 'https://esm.sh').replace(/\/+$/, '');
|
|
27
59
|
const dependencies = options.dependencies ?? {};
|
|
60
|
+
const manifests = options.manifests ?? {};
|
|
28
61
|
const dev = options.dev ?? true;
|
|
29
62
|
|
|
30
|
-
// Pin every declared dependency into each package's own graph, so `react-dom`
|
|
31
|
-
// and the app share ONE `react` — two copies is the classic "invalid hook call".
|
|
32
63
|
const pinned = Object.entries(dependencies)
|
|
33
64
|
.filter(([, range]) => isRegistryRange(range))
|
|
34
|
-
.
|
|
35
|
-
.sort();
|
|
65
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
36
66
|
|
|
37
67
|
return {
|
|
38
68
|
urlFor(name, subpath) {
|
|
39
69
|
const range = dependencies[name];
|
|
40
|
-
const
|
|
70
|
+
const declared = !!range && isRegistryRange(range);
|
|
71
|
+
const versioned = declared ? `${name}@${range}` : name;
|
|
72
|
+
// ONE React means the app must import the very module esm.sh links a package's
|
|
73
|
+
// own imports to. When esm.sh builds `react-dom?deps=react@x`, its `import
|
|
74
|
+
// 'react'` becomes `react@x` pinned with only the deps REACT itself imports
|
|
75
|
+
// (none), i.e. the plain build. Pinning every other declared package onto
|
|
76
|
+
// `react` too made the app load a second `?deps=react-dom,…` copy, and its
|
|
77
|
+
// first `useState` read a null dispatcher. So a declared package carries only
|
|
78
|
+
// the pins it imports. An undeclared one (nothing links to it by name) and one
|
|
79
|
+
// whose manifest could not load carry every pin, which is what dedupes the
|
|
80
|
+
// packages THEY import.
|
|
81
|
+
const manifest = declared ? manifests[name] : undefined;
|
|
82
|
+
const deps = pinned
|
|
83
|
+
.filter(([other]) => other !== name && (!manifest || importsPackage(manifest, other)))
|
|
84
|
+
.map(([other, otherRange]) => `${other}@${otherRange}`);
|
|
41
85
|
const params: string[] = [];
|
|
42
|
-
const deps = pinned.filter((entry) => !entry.startsWith(name + '@'));
|
|
43
86
|
if (deps.length) params.push('deps=' + deps.map(encodeURIComponent).join(','));
|
|
44
87
|
if (dev) params.push('dev');
|
|
45
88
|
return `${origin}/${versioned}${subpath}${params.length ? '?' + params.join('&') : ''}`;
|
|
46
89
|
},
|
|
47
90
|
};
|
|
48
91
|
}
|
|
92
|
+
|
|
93
|
+
export interface ManifestLoadOptions {
|
|
94
|
+
/** Defaults to https://esm.sh, which serves `<name>@<range>/package.json`. */
|
|
95
|
+
origin?: string;
|
|
96
|
+
fetch?: (url: string) => Promise<{ ok: boolean; json(): Promise<unknown> }>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const manifestCache = new Map<string, Promise<PackageDependencyFields | undefined>>();
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The dependency fields of every declared registry package, fetched in parallel and
|
|
103
|
+
* kept for the session (a range resolves the same way for its lifetime). A package
|
|
104
|
+
* whose manifest cannot be fetched is simply absent, and `createEsmShCdn` falls
|
|
105
|
+
* back to pinning everything onto it.
|
|
106
|
+
*/
|
|
107
|
+
export async function loadPackageManifests(
|
|
108
|
+
dependencies: Record<string, string>,
|
|
109
|
+
options: ManifestLoadOptions = {},
|
|
110
|
+
): Promise<Record<string, PackageDependencyFields>> {
|
|
111
|
+
const origin = (options.origin ?? 'https://esm.sh').replace(/\/+$/, '');
|
|
112
|
+
const fetcher = options.fetch ?? (typeof fetch === 'function' ? (url: string) => fetch(url) : undefined);
|
|
113
|
+
if (!fetcher) return {};
|
|
114
|
+
const entries = await Promise.all(
|
|
115
|
+
Object.entries(dependencies)
|
|
116
|
+
.filter(([, range]) => isRegistryRange(range))
|
|
117
|
+
.map(async ([name, range]) => {
|
|
118
|
+
const url = `${origin}/${name}@${range}/package.json`;
|
|
119
|
+
let pending = manifestCache.get(url);
|
|
120
|
+
if (!pending) {
|
|
121
|
+
pending = fetcher(url)
|
|
122
|
+
.then(async (res) => (res.ok ? ((await res.json()) as PackageDependencyFields) : undefined))
|
|
123
|
+
.catch(() => undefined);
|
|
124
|
+
manifestCache.set(url, pending);
|
|
125
|
+
}
|
|
126
|
+
return [name, await pending] as const;
|
|
127
|
+
}),
|
|
128
|
+
);
|
|
129
|
+
const loaded: Record<string, PackageDependencyFields> = {};
|
|
130
|
+
for (const [name, manifest] of entries) if (manifest) loaded[name] = manifest;
|
|
131
|
+
return loaded;
|
|
132
|
+
}
|
package/src/projectConfig.ts
CHANGED
|
@@ -17,8 +17,18 @@ export const CONFIG_FILES = [
|
|
|
17
17
|
'/.env.local',
|
|
18
18
|
'/.env.development',
|
|
19
19
|
'/.env.development.local',
|
|
20
|
+
'/.env.production',
|
|
21
|
+
'/.env.production.local',
|
|
20
22
|
] as const;
|
|
21
23
|
|
|
24
|
+
/** Which `.env.<mode>` files apply: the dev server reads development, a build production. */
|
|
25
|
+
export type BuildMode = 'development' | 'production';
|
|
26
|
+
|
|
27
|
+
/** Vite's load order — later files win. */
|
|
28
|
+
export function envFiles(mode: BuildMode): string[] {
|
|
29
|
+
return ['/.env', '/.env.local', `/.env.${mode}`, `/.env.${mode}.local`];
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
export interface PathAlias {
|
|
23
33
|
/** The specifier prefix, without the trailing `*` (`@/`). Exact when `wildcard` is false. */
|
|
24
34
|
prefix: string;
|
|
@@ -83,9 +93,25 @@ function readDependencies(fs: VirtualFileSystem): Record<string, string> {
|
|
|
83
93
|
return out;
|
|
84
94
|
}
|
|
85
95
|
|
|
96
|
+
/**
|
|
97
|
+
* The root tsconfig's compiler options. Current Vite templates (React, Vue,
|
|
98
|
+
* Svelte) keep a root `tsconfig.json` with only `references`, and the app's real
|
|
99
|
+
* options — `paths` included — in `tsconfig.app.json`; options missing from the
|
|
100
|
+
* root are taken from the referenced configs, in order.
|
|
101
|
+
*/
|
|
86
102
|
function readCompilerOptions(fs: VirtualFileSystem): Record<string, unknown> {
|
|
87
103
|
const tsconfig = readJson(fs, '/tsconfig.json') ?? readJson(fs, '/jsconfig.json') ?? {};
|
|
88
|
-
|
|
104
|
+
const options = { ...asRecord(tsconfig.compilerOptions) };
|
|
105
|
+
const references = Array.isArray(tsconfig.references) ? tsconfig.references : [];
|
|
106
|
+
for (const reference of references) {
|
|
107
|
+
const target = asRecord(reference).path;
|
|
108
|
+
if (typeof target !== 'string') continue;
|
|
109
|
+
const file = target.endsWith('.json') ? join('/', target) : join('/', target, 'tsconfig.json');
|
|
110
|
+
for (const [key, value] of Object.entries(asRecord(readJson(fs, file)?.compilerOptions))) {
|
|
111
|
+
if (!(key in options)) options[key] = value;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return options;
|
|
89
115
|
}
|
|
90
116
|
|
|
91
117
|
function readAliases(options: Record<string, unknown>): PathAlias[] {
|
|
@@ -131,27 +157,28 @@ export function parseDotenv(text: string): Record<string, string> {
|
|
|
131
157
|
return out;
|
|
132
158
|
}
|
|
133
159
|
|
|
134
|
-
function readEnv(fs: VirtualFileSystem): Record<string, string> {
|
|
160
|
+
function readEnv(fs: VirtualFileSystem, mode: BuildMode): Record<string, string> {
|
|
135
161
|
const env: Record<string, string> = {};
|
|
136
|
-
for (const file of
|
|
137
|
-
if (!file.startsWith('/.env')) continue;
|
|
162
|
+
for (const file of envFiles(mode)) {
|
|
138
163
|
const text = fs.readText(file);
|
|
139
164
|
if (text !== undefined) Object.assign(env, parseDotenv(text));
|
|
140
165
|
}
|
|
141
166
|
return env;
|
|
142
167
|
}
|
|
143
168
|
|
|
144
|
-
export function readProjectConfig(fs: VirtualFileSystem): ProjectConfig {
|
|
169
|
+
export function readProjectConfig(fs: VirtualFileSystem, mode: BuildMode = 'development'): ProjectConfig {
|
|
145
170
|
const options = readCompilerOptions(fs);
|
|
146
171
|
return {
|
|
147
172
|
dependencies: readDependencies(fs),
|
|
148
173
|
aliases: readAliases(options),
|
|
149
174
|
jsx: readJsx(options),
|
|
150
|
-
env: readEnv(fs),
|
|
175
|
+
env: readEnv(fs, mode),
|
|
151
176
|
};
|
|
152
177
|
}
|
|
153
178
|
|
|
154
179
|
/** True when a change to `path` invalidates the derived {@link ProjectConfig}. */
|
|
155
180
|
export function isConfigFile(path: string): boolean {
|
|
156
|
-
|
|
181
|
+
const normalized = normalizePath(path);
|
|
182
|
+
// Any root tsconfig: the root one may reference `tsconfig.app.json` and friends.
|
|
183
|
+
return (CONFIG_FILES as readonly string[]).includes(normalized) || /^\/tsconfig[^/]*\.json$/.test(normalized);
|
|
157
184
|
}
|