@vibesdotdev/infra-core 0.0.1 → 1.0.0-rc.11
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/LICENSE +18 -0
- package/README.md +34 -63
- package/dist/bootstrap/seed.descriptor.d.ts +1 -1
- package/dist/bootstrap/seed.descriptor.d.ts.map +1 -1
- package/dist/bootstrap/seed.descriptor.js +1 -1
- package/dist/bootstrap/seed.descriptor.js.map +1 -1
- package/dist/bootstrap/seed.impl-shape.d.ts +1 -1
- package/dist/bootstrap/seed.impl-shape.d.ts.map +1 -1
- package/dist/bootstrap/seed.kind.d.ts +1 -3
- package/dist/bootstrap/seed.kind.d.ts.map +1 -1
- package/dist/bootstrap/seed.kind.js +17 -4
- package/dist/bootstrap/seed.kind.js.map +1 -1
- package/dist/bootstrap/seed.runner.d.ts +9 -2
- package/dist/bootstrap/seed.runner.d.ts.map +1 -1
- package/dist/bootstrap/seed.runner.js +37 -18
- package/dist/bootstrap/seed.runner.js.map +1 -1
- package/dist/capped-id.d.ts +19 -0
- package/dist/capped-id.d.ts.map +1 -0
- package/dist/capped-id.js +64 -0
- package/dist/capped-id.js.map +1 -0
- package/dist/cli/generate/artifact/artifact.cli-command.descriptor.d.ts +23 -0
- package/dist/cli/generate/artifact/artifact.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/generate/artifact/artifact.cli-command.descriptor.js +33 -0
- package/dist/cli/generate/artifact/artifact.cli-command.descriptor.js.map +1 -0
- package/dist/cli/generate/artifact/artifact.cli-command.impl.d.ts +24 -0
- package/dist/cli/generate/artifact/artifact.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/generate/artifact/artifact.cli-command.impl.js +73 -0
- package/dist/cli/generate/artifact/artifact.cli-command.impl.js.map +1 -0
- package/dist/cli/generate/context.d.ts +17 -0
- package/dist/cli/generate/context.d.ts.map +1 -0
- package/dist/cli/generate/context.js +24 -0
- package/dist/cli/generate/context.js.map +1 -0
- package/dist/cli/generate/generate/generate.cli-command.descriptor.d.ts +30 -0
- package/dist/cli/generate/generate/generate.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/generate/generate/generate.cli-command.descriptor.js +25 -0
- package/dist/cli/generate/generate/generate.cli-command.descriptor.js.map +1 -0
- package/dist/cli/generate/generate/generate.cli-command.impl.d.ts +25 -0
- package/dist/cli/generate/generate/generate.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/generate/generate/generate.cli-command.impl.js +64 -0
- package/dist/cli/generate/generate/generate.cli-command.impl.js.map +1 -0
- package/dist/cli/generate/generate-core.d.ts +51 -0
- package/dist/cli/generate/generate-core.d.ts.map +1 -0
- package/dist/cli/generate/generate-core.js +172 -0
- package/dist/cli/generate/generate-core.js.map +1 -0
- package/dist/cli/generate/index.d.ts +5 -0
- package/dist/cli/generate/index.d.ts.map +1 -0
- package/dist/cli/generate/index.js +5 -0
- package/dist/cli/generate/index.js.map +1 -0
- package/dist/credentials/resolve.d.ts +82 -22
- package/dist/credentials/resolve.d.ts.map +1 -1
- package/dist/credentials/resolve.js +251 -77
- package/dist/credentials/resolve.js.map +1 -1
- package/dist/deployment-budget.d.ts +319 -0
- package/dist/deployment-budget.d.ts.map +1 -0
- package/dist/deployment-budget.js +660 -0
- package/dist/deployment-budget.js.map +1 -0
- package/dist/deployment-environment.d.ts +30 -0
- package/dist/deployment-environment.d.ts.map +1 -0
- package/dist/deployment-environment.js +53 -0
- package/dist/deployment-environment.js.map +1 -0
- package/dist/deployment-graph.d.ts +185 -0
- package/dist/deployment-graph.d.ts.map +1 -0
- package/dist/deployment-graph.js +705 -0
- package/dist/deployment-graph.js.map +1 -0
- package/dist/deployment.d.ts +25 -4
- package/dist/deployment.d.ts.map +1 -1
- package/dist/deployment.js +105 -0
- package/dist/deployment.js.map +1 -1
- package/dist/doks/cloud/base.d.ts +49 -0
- package/dist/doks/cloud/base.d.ts.map +1 -0
- package/dist/doks/cloud/base.js +138 -0
- package/dist/doks/cloud/base.js.map +1 -0
- package/dist/doks/cloud/factory.d.ts +18 -0
- package/dist/doks/cloud/factory.d.ts.map +1 -0
- package/dist/doks/cloud/factory.js +22 -0
- package/dist/doks/cloud/factory.js.map +1 -0
- package/dist/doks/cloud/index.d.ts +5 -0
- package/dist/doks/cloud/index.d.ts.map +1 -0
- package/dist/doks/cloud/index.js +4 -0
- package/dist/doks/cloud/index.js.map +1 -0
- package/dist/doks/types.d.ts +95 -0
- package/dist/doks/types.d.ts.map +1 -0
- package/dist/doks/types.js +14 -0
- package/dist/doks/types.js.map +1 -0
- package/dist/generate/index.d.ts +29 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +28 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/generate/infra-generate.plugin.d.ts +3 -0
- package/dist/generate/infra-generate.plugin.d.ts.map +1 -0
- package/dist/generate/infra-generate.plugin.js +23 -0
- package/dist/generate/infra-generate.plugin.js.map +1 -0
- package/dist/generate/plugin.d.ts +2 -0
- package/dist/generate/plugin.d.ts.map +1 -0
- package/dist/generate/plugin.js +2 -0
- package/dist/generate/plugin.js.map +1 -0
- package/dist/heartbeat/cron-heartbeat.d.ts +97 -0
- package/dist/heartbeat/cron-heartbeat.d.ts.map +1 -0
- package/dist/heartbeat/cron-heartbeat.js +200 -0
- package/dist/heartbeat/cron-heartbeat.js.map +1 -0
- package/dist/index.d.ts +37 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -14
- package/dist/index.js.map +1 -1
- package/dist/infra.plugin.d.ts +1 -1
- package/dist/infra.plugin.d.ts.map +1 -1
- package/dist/infra.plugin.js +64 -12
- package/dist/infra.plugin.js.map +1 -1
- package/dist/kinds/alerts.kind.d.ts +64 -25
- package/dist/kinds/alerts.kind.d.ts.map +1 -1
- package/dist/kinds/alerts.kind.js +43 -16
- package/dist/kinds/alerts.kind.js.map +1 -1
- package/dist/kinds/artifact.kind.d.ts +58 -10
- package/dist/kinds/artifact.kind.d.ts.map +1 -1
- package/dist/kinds/artifact.kind.js +26 -9
- package/dist/kinds/artifact.kind.js.map +1 -1
- package/dist/kinds/billing.kind.d.ts +88 -0
- package/dist/kinds/billing.kind.d.ts.map +1 -0
- package/dist/kinds/billing.kind.js +48 -0
- package/dist/kinds/billing.kind.js.map +1 -0
- package/dist/kinds/build-job.kind.d.ts +383 -0
- package/dist/kinds/build-job.kind.d.ts.map +1 -0
- package/dist/kinds/build-job.kind.js +218 -0
- package/dist/kinds/build-job.kind.js.map +1 -0
- package/dist/kinds/cache-byte-store.d.ts +23 -0
- package/dist/kinds/cache-byte-store.d.ts.map +1 -0
- package/dist/kinds/cache-byte-store.js +9 -0
- package/dist/kinds/cache-byte-store.js.map +1 -0
- package/dist/kinds/cache.kind.d.ts +38 -94
- package/dist/kinds/cache.kind.d.ts.map +1 -1
- package/dist/kinds/cache.kind.js +39 -50
- package/dist/kinds/cache.kind.js.map +1 -1
- package/dist/kinds/cluster.kind.d.ts +154 -0
- package/dist/kinds/cluster.kind.d.ts.map +1 -0
- package/dist/kinds/cluster.kind.js +99 -0
- package/dist/kinds/cluster.kind.js.map +1 -0
- package/dist/kinds/compute-source.kind.d.ts +155 -0
- package/dist/kinds/compute-source.kind.d.ts.map +1 -0
- package/dist/kinds/compute-source.kind.js +158 -0
- package/dist/kinds/compute-source.kind.js.map +1 -0
- package/dist/kinds/container-registry.kind.d.ts +62 -0
- package/dist/kinds/container-registry.kind.d.ts.map +1 -0
- package/dist/kinds/container-registry.kind.js +47 -0
- package/dist/kinds/container-registry.kind.js.map +1 -0
- package/dist/kinds/database-migrator.kind.d.ts +6 -0
- package/dist/kinds/database-migrator.kind.d.ts.map +1 -0
- package/dist/kinds/database-migrator.kind.js +28 -0
- package/dist/kinds/database-migrator.kind.js.map +1 -0
- package/dist/kinds/database.kind.d.ts +114 -93
- package/dist/kinds/database.kind.d.ts.map +1 -1
- package/dist/kinds/database.kind.js +93 -54
- package/dist/kinds/database.kind.js.map +1 -1
- package/dist/kinds/deployment-provider.kind.d.ts +5 -0
- package/dist/kinds/deployment-provider.kind.d.ts.map +1 -0
- package/dist/kinds/deployment-provider.kind.js +11 -0
- package/dist/kinds/deployment-provider.kind.js.map +1 -0
- package/dist/kinds/discovery.d.ts +5 -12
- package/dist/kinds/discovery.d.ts.map +1 -1
- package/dist/kinds/discovery.js +5 -17
- package/dist/kinds/discovery.js.map +1 -1
- package/dist/kinds/dns.kind.d.ts +162 -0
- package/dist/kinds/dns.kind.d.ts.map +1 -0
- package/dist/kinds/dns.kind.js +54 -0
- package/dist/kinds/dns.kind.js.map +1 -0
- package/dist/kinds/drift.kind.d.ts +115 -0
- package/dist/kinds/drift.kind.d.ts.map +1 -0
- package/dist/kinds/drift.kind.js +60 -0
- package/dist/kinds/drift.kind.js.map +1 -0
- package/dist/kinds/edge-hostname.kind.d.ts +124 -0
- package/dist/kinds/edge-hostname.kind.d.ts.map +1 -0
- package/dist/kinds/edge-hostname.kind.js +87 -0
- package/dist/kinds/edge-hostname.kind.js.map +1 -0
- package/dist/kinds/edge-tls.kind.d.ts +194 -0
- package/dist/kinds/edge-tls.kind.d.ts.map +1 -0
- package/dist/kinds/edge-tls.kind.js +58 -0
- package/dist/kinds/edge-tls.kind.js.map +1 -0
- package/dist/kinds/firewall.kind.d.ts +92 -0
- package/dist/kinds/firewall.kind.d.ts.map +1 -0
- package/dist/kinds/firewall.kind.js +59 -0
- package/dist/kinds/firewall.kind.js.map +1 -0
- package/dist/kinds/git-hosting.kind.d.ts +36 -38
- package/dist/kinds/git-hosting.kind.d.ts.map +1 -1
- package/dist/kinds/git-hosting.kind.js +23 -34
- package/dist/kinds/git-hosting.kind.js.map +1 -1
- package/dist/kinds/index.d.ts +41 -15
- package/dist/kinds/index.d.ts.map +1 -1
- package/dist/kinds/index.js +40 -14
- package/dist/kinds/index.js.map +1 -1
- package/dist/kinds/inventory.kind.d.ts +245 -0
- package/dist/kinds/inventory.kind.d.ts.map +1 -0
- package/dist/kinds/inventory.kind.js +243 -0
- package/dist/kinds/inventory.kind.js.map +1 -0
- package/dist/kinds/load-balancer.kind.d.ts +135 -0
- package/dist/kinds/load-balancer.kind.d.ts.map +1 -0
- package/dist/kinds/load-balancer.kind.js +71 -0
- package/dist/kinds/load-balancer.kind.js.map +1 -0
- package/dist/kinds/logs.kind.d.ts +74 -3
- package/dist/kinds/logs.kind.d.ts.map +1 -1
- package/dist/kinds/logs.kind.js +26 -17
- package/dist/kinds/logs.kind.js.map +1 -1
- package/dist/kinds/nfs.kind.d.ts +67 -0
- package/dist/kinds/nfs.kind.d.ts.map +1 -0
- package/dist/kinds/nfs.kind.js +45 -0
- package/dist/kinds/nfs.kind.js.map +1 -0
- package/dist/kinds/node-pool.kind.d.ts +134 -0
- package/dist/kinds/node-pool.kind.d.ts.map +1 -0
- package/dist/kinds/node-pool.kind.js +88 -0
- package/dist/kinds/node-pool.kind.js.map +1 -0
- package/dist/kinds/object-storage.kind.d.ts +50 -24
- package/dist/kinds/object-storage.kind.d.ts.map +1 -1
- package/dist/kinds/object-storage.kind.js +40 -23
- package/dist/kinds/object-storage.kind.js.map +1 -1
- package/dist/kinds/observability.kind.d.ts +104 -6
- package/dist/kinds/observability.kind.d.ts.map +1 -1
- package/dist/kinds/observability.kind.js +67 -9
- package/dist/kinds/observability.kind.js.map +1 -1
- package/dist/kinds/package-registry.kind.d.ts +141 -35
- package/dist/kinds/package-registry.kind.d.ts.map +1 -1
- package/dist/kinds/package-registry.kind.js +55 -25
- package/dist/kinds/package-registry.kind.js.map +1 -1
- package/dist/kinds/queue.kind.d.ts +67 -63
- package/dist/kinds/queue.kind.d.ts.map +1 -1
- package/dist/kinds/queue.kind.js +55 -33
- package/dist/kinds/queue.kind.js.map +1 -1
- package/dist/kinds/read-descriptor.d.ts +15 -0
- package/dist/kinds/read-descriptor.d.ts.map +1 -0
- package/dist/kinds/read-descriptor.js +11 -0
- package/dist/kinds/read-descriptor.js.map +1 -0
- package/dist/kinds/rum.kind.d.ts +36 -6
- package/dist/kinds/rum.kind.d.ts.map +1 -1
- package/dist/kinds/rum.kind.js +6 -7
- package/dist/kinds/rum.kind.js.map +1 -1
- package/dist/kinds/sandbox.kind.d.ts +136 -40
- package/dist/kinds/sandbox.kind.d.ts.map +1 -1
- package/dist/kinds/sandbox.kind.js +82 -43
- package/dist/kinds/sandbox.kind.js.map +1 -1
- package/dist/kinds/select-compute-source.d.ts +72 -0
- package/dist/kinds/select-compute-source.d.ts.map +1 -0
- package/dist/kinds/select-compute-source.js +170 -0
- package/dist/kinds/select-compute-source.js.map +1 -0
- package/dist/kinds/service-release.kind.d.ts +771 -0
- package/dist/kinds/service-release.kind.d.ts.map +1 -0
- package/dist/kinds/service-release.kind.js +676 -0
- package/dist/kinds/service-release.kind.js.map +1 -0
- package/dist/kinds/spend-guard.kind.d.ts +41 -0
- package/dist/kinds/spend-guard.kind.d.ts.map +1 -0
- package/dist/kinds/spend-guard.kind.js +140 -0
- package/dist/kinds/spend-guard.kind.js.map +1 -0
- package/dist/kinds/utilization.kind.d.ts +88 -0
- package/dist/kinds/utilization.kind.d.ts.map +1 -0
- package/dist/kinds/utilization.kind.js +62 -0
- package/dist/kinds/utilization.kind.js.map +1 -0
- package/dist/kinds/volume.kind.d.ts +54 -0
- package/dist/kinds/volume.kind.d.ts.map +1 -0
- package/dist/kinds/volume.kind.js +39 -0
- package/dist/kinds/volume.kind.js.map +1 -0
- package/dist/kinds/vpc.kind.d.ts +61 -0
- package/dist/kinds/vpc.kind.d.ts.map +1 -0
- package/dist/kinds/vpc.kind.js +51 -0
- package/dist/kinds/vpc.kind.js.map +1 -0
- package/dist/kinds/web-app.kind.d.ts +118 -45
- package/dist/kinds/web-app.kind.d.ts.map +1 -1
- package/dist/kinds/web-app.kind.js +69 -42
- package/dist/kinds/web-app.kind.js.map +1 -1
- package/dist/kinds/worker.kind.d.ts +129 -188
- package/dist/kinds/worker.kind.d.ts.map +1 -1
- package/dist/kinds/worker.kind.js +45 -123
- package/dist/kinds/worker.kind.js.map +1 -1
- package/dist/schemas/database-migration.d.ts +173 -0
- package/dist/schemas/database-migration.d.ts.map +1 -0
- package/dist/schemas/database-migration.js +88 -0
- package/dist/schemas/database-migration.js.map +1 -0
- package/dist/schemas/deployment-environment.d.ts +11 -0
- package/dist/schemas/deployment-environment.d.ts.map +1 -0
- package/dist/schemas/deployment-environment.js +9 -0
- package/dist/schemas/deployment-environment.js.map +1 -0
- package/dist/schemas/deployment-provider.d.ts +383 -0
- package/dist/schemas/deployment-provider.d.ts.map +1 -0
- package/dist/schemas/deployment-provider.js +211 -0
- package/dist/schemas/deployment-provider.js.map +1 -0
- package/dist/schemas/log-stream.d.ts +27 -0
- package/dist/schemas/log-stream.d.ts.map +1 -0
- package/dist/schemas/log-stream.js +31 -0
- package/dist/schemas/log-stream.js.map +1 -0
- package/dist/schemas/spend-guard.d.ts +155 -0
- package/dist/schemas/spend-guard.d.ts.map +1 -0
- package/dist/schemas/spend-guard.js +61 -0
- package/dist/schemas/spend-guard.js.map +1 -0
- package/dist/schemas.d.ts +195 -20
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +151 -31
- package/dist/schemas.js.map +1 -1
- package/dist/service.d.ts +87 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +199 -0
- package/dist/service.js.map +1 -0
- package/dist/settle-work.d.ts +20 -0
- package/dist/settle-work.d.ts.map +1 -0
- package/dist/settle-work.js +22 -0
- package/dist/settle-work.js.map +1 -0
- package/dist/web-app-projection.d.ts +208 -0
- package/dist/web-app-projection.d.ts.map +1 -0
- package/dist/web-app-projection.js +95 -0
- package/dist/web-app-projection.js.map +1 -0
- package/package.json +123 -40
- package/SPEC.md +0 -169
- package/src/bootstrap/index.ts +0 -15
- package/src/bootstrap/seed.descriptor.ts +0 -24
- package/src/bootstrap/seed.impl-shape.ts +0 -5
- package/src/bootstrap/seed.kind.ts +0 -26
- package/src/bootstrap/seed.runner.ts +0 -87
- package/src/credentials/resolve.ts +0 -205
- package/src/deployment.ts +0 -57
- package/src/index.ts +0 -149
- package/src/infra.plugin.ts +0 -54
- package/src/kinds/alerts.kind.ts +0 -164
- package/src/kinds/artifact.kind.ts +0 -96
- package/src/kinds/cache.kind.ts +0 -104
- package/src/kinds/database.kind.ts +0 -120
- package/src/kinds/discovery.ts +0 -26
- package/src/kinds/git-hosting.kind.ts +0 -100
- package/src/kinds/index.ts +0 -139
- package/src/kinds/logs.kind.ts +0 -104
- package/src/kinds/object-storage.kind.ts +0 -101
- package/src/kinds/observability.kind.ts +0 -178
- package/src/kinds/package-registry.kind.ts +0 -95
- package/src/kinds/queue.kind.ts +0 -102
- package/src/kinds/rum.kind.ts +0 -135
- package/src/kinds/sandbox.kind.ts +0 -115
- package/src/kinds/web-app.kind.ts +0 -103
- package/src/kinds/worker.kind.ts +0 -203
- package/src/schemas.ts +0 -127
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The module graph a provider bundles into one Worker script, read from the built output before
|
|
3
|
+
* the provider's bundler runs.
|
|
4
|
+
*
|
|
5
|
+
* The walk starts at the Worker entries and follows what the bundler follows: relative imports,
|
|
6
|
+
* bare package specifiers resolved through `node_modules` with the provider's export conditions,
|
|
7
|
+
* dynamic imports and CommonJS `require` calls. Built-in modules (`node:tls`, `cloudflare:workers`)
|
|
8
|
+
* are leaves the provider supplies or refuses. A bundler's own module markers (`//#region <source>`)
|
|
9
|
+
* name the source modules a built chunk inlined, so a chunk is attributed to the packages it really
|
|
10
|
+
* carries. Specifiers are read by a lexer that skips comments, strings and regular expressions, so
|
|
11
|
+
* prose about `require('fs')` is not an import.
|
|
12
|
+
*
|
|
13
|
+
* The measurement is pre-minify and pre-tree-shake: whole modules, as the bundler reads them.
|
|
14
|
+
*/
|
|
15
|
+
import * as z from 'zod/v4';
|
|
16
|
+
import { jsoncCodec } from '@vibesdotdev/shared/jsonc';
|
|
17
|
+
const KEYWORDS_BEFORE_EXPRESSION = new Set([
|
|
18
|
+
'return', 'typeof', 'instanceof', 'case', 'do', 'else', 'in', 'of', 'new', 'delete', 'void', 'throw', 'yield', 'await'
|
|
19
|
+
]);
|
|
20
|
+
const PUNCTUATION_BEFORE_EXPRESSION = new Set(['(', ',', '=', ':', '[', '!', '&', '|', '?', '{', '}', ';', '+', '-', '*', '%', '<', '>', '~', '^']);
|
|
21
|
+
function isIdentifierStart(char) {
|
|
22
|
+
return /[A-Za-z_$\u0080-]/.test(char);
|
|
23
|
+
}
|
|
24
|
+
function isIdentifierPart(char) {
|
|
25
|
+
return /[A-Za-z0-9_$\u0080-]/.test(char);
|
|
26
|
+
}
|
|
27
|
+
const encoder = new TextEncoder();
|
|
28
|
+
export function utf8Bytes(text) {
|
|
29
|
+
return encoder.encode(text).length;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The import, export-from, dynamic-import and `require` specifiers of one JavaScript or TypeScript
|
|
33
|
+
* module, and the source regions a bundler marked in it. Type-only imports and exports carry no
|
|
34
|
+
* runtime module and are skipped. Only literal specifiers are read: a computed `import(name)` names
|
|
35
|
+
* no module a bundler can include either.
|
|
36
|
+
*/
|
|
37
|
+
export function scanModule(text) {
|
|
38
|
+
const specifiers = [];
|
|
39
|
+
const regionStarts = [];
|
|
40
|
+
const regions = [];
|
|
41
|
+
const length = text.length;
|
|
42
|
+
let index = 0;
|
|
43
|
+
/** The last significant token, to tell a regular expression from a division. */
|
|
44
|
+
let previous = '';
|
|
45
|
+
let previousWord = '';
|
|
46
|
+
/** Inside an `import` or `export` statement whose `from` is still to come. */
|
|
47
|
+
let pendingStatement;
|
|
48
|
+
/** Open template literal nesting: each entry is the brace depth at which its `${` opened. */
|
|
49
|
+
const templates = [];
|
|
50
|
+
let braceDepth = 0;
|
|
51
|
+
const skipSpace = (from) => {
|
|
52
|
+
let position = from;
|
|
53
|
+
while (position < length) {
|
|
54
|
+
const char = text[position];
|
|
55
|
+
if (char === ' ' || char === '\t' || char === '\n' || char === '\r')
|
|
56
|
+
position += 1;
|
|
57
|
+
else if (char === '/' && text[position + 1] === '/') {
|
|
58
|
+
while (position < length && text[position] !== '\n')
|
|
59
|
+
position += 1;
|
|
60
|
+
}
|
|
61
|
+
else if (char === '/' && text[position + 1] === '*') {
|
|
62
|
+
const end = text.indexOf('*/', position + 2);
|
|
63
|
+
position = end < 0 ? length : end + 2;
|
|
64
|
+
}
|
|
65
|
+
else
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
return position;
|
|
69
|
+
};
|
|
70
|
+
/** A string literal at `from`: its value and end, or undefined. Template literals count only without substitutions. */
|
|
71
|
+
const literalAt = (from) => {
|
|
72
|
+
const quote = text[from];
|
|
73
|
+
if (quote !== '"' && quote !== "'" && quote !== '`')
|
|
74
|
+
return undefined;
|
|
75
|
+
let position = from + 1;
|
|
76
|
+
let value = '';
|
|
77
|
+
while (position < length && text[position] !== quote) {
|
|
78
|
+
if (text[position] === '\\') {
|
|
79
|
+
value += text[position + 1] ?? '';
|
|
80
|
+
position += 2;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (quote === '`' && text[position] === '$' && text[position + 1] === '{')
|
|
84
|
+
return undefined;
|
|
85
|
+
if (quote !== '`' && text[position] === '\n')
|
|
86
|
+
return undefined;
|
|
87
|
+
value += text[position];
|
|
88
|
+
position += 1;
|
|
89
|
+
}
|
|
90
|
+
return position < length ? { value, end: position + 1 } : undefined;
|
|
91
|
+
};
|
|
92
|
+
const wordAt = (from) => {
|
|
93
|
+
let end = from;
|
|
94
|
+
while (end < length && isIdentifierPart(text[end] ?? ''))
|
|
95
|
+
end += 1;
|
|
96
|
+
return text.slice(from, end);
|
|
97
|
+
};
|
|
98
|
+
const skipString = (from, quote) => {
|
|
99
|
+
let position = from + 1;
|
|
100
|
+
while (position < length) {
|
|
101
|
+
const char = text[position];
|
|
102
|
+
if (char === '\\')
|
|
103
|
+
position += 2;
|
|
104
|
+
else if (char === quote || char === '\n')
|
|
105
|
+
return position + 1;
|
|
106
|
+
else
|
|
107
|
+
position += 1;
|
|
108
|
+
}
|
|
109
|
+
return length;
|
|
110
|
+
};
|
|
111
|
+
/** Skip template text from `from` (just after a backtick or a closing `}`); stops after the closing backtick or at a `${`. */
|
|
112
|
+
const skipTemplateText = (from) => {
|
|
113
|
+
let position = from;
|
|
114
|
+
while (position < length) {
|
|
115
|
+
const char = text[position];
|
|
116
|
+
if (char === '\\')
|
|
117
|
+
position += 2;
|
|
118
|
+
else if (char === '`')
|
|
119
|
+
return position + 1;
|
|
120
|
+
else if (char === '$' && text[position + 1] === '{') {
|
|
121
|
+
templates.push(braceDepth);
|
|
122
|
+
braceDepth += 1;
|
|
123
|
+
return position + 2;
|
|
124
|
+
}
|
|
125
|
+
else
|
|
126
|
+
position += 1;
|
|
127
|
+
}
|
|
128
|
+
return length;
|
|
129
|
+
};
|
|
130
|
+
const skipRegex = (from) => {
|
|
131
|
+
let position = from + 1;
|
|
132
|
+
let inClass = false;
|
|
133
|
+
while (position < length) {
|
|
134
|
+
const char = text[position];
|
|
135
|
+
if (char === '\\')
|
|
136
|
+
position += 2;
|
|
137
|
+
else if (char === '\n')
|
|
138
|
+
return position;
|
|
139
|
+
else if (inClass) {
|
|
140
|
+
if (char === ']')
|
|
141
|
+
inClass = false;
|
|
142
|
+
position += 1;
|
|
143
|
+
}
|
|
144
|
+
else if (char === '[') {
|
|
145
|
+
inClass = true;
|
|
146
|
+
position += 1;
|
|
147
|
+
}
|
|
148
|
+
else if (char === '/') {
|
|
149
|
+
position += 1;
|
|
150
|
+
while (position < length && isIdentifierPart(text[position] ?? ''))
|
|
151
|
+
position += 1;
|
|
152
|
+
return position;
|
|
153
|
+
}
|
|
154
|
+
else
|
|
155
|
+
position += 1;
|
|
156
|
+
}
|
|
157
|
+
return length;
|
|
158
|
+
};
|
|
159
|
+
while (index < length) {
|
|
160
|
+
const char = text[index] ?? '';
|
|
161
|
+
const next = text[index + 1];
|
|
162
|
+
if (char === '/' && next === '/') {
|
|
163
|
+
const end = text.indexOf('\n', index);
|
|
164
|
+
const lineEnd = end < 0 ? length : end;
|
|
165
|
+
const comment = text.slice(index + 2, lineEnd);
|
|
166
|
+
if (comment.startsWith('#region '))
|
|
167
|
+
regionStarts.push({ source: comment.slice('#region '.length).trim(), offset: index });
|
|
168
|
+
else if (comment.startsWith('#endregion')) {
|
|
169
|
+
const open = regionStarts.pop();
|
|
170
|
+
if (open)
|
|
171
|
+
regions.push({ source: open.source, bytes: utf8Bytes(text.slice(open.offset, lineEnd)) });
|
|
172
|
+
}
|
|
173
|
+
index = lineEnd;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (char === '/' && next === '*') {
|
|
177
|
+
const end = text.indexOf('*/', index + 2);
|
|
178
|
+
index = end < 0 ? length : end + 2;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (char === '"' || char === "'") {
|
|
182
|
+
index = skipString(index, char);
|
|
183
|
+
previous = '"';
|
|
184
|
+
previousWord = '';
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (char === '`') {
|
|
188
|
+
index = skipTemplateText(index + 1);
|
|
189
|
+
previous = '`';
|
|
190
|
+
previousWord = '';
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (char === '/') {
|
|
194
|
+
const expression = previous === '' || PUNCTUATION_BEFORE_EXPRESSION.has(previous) || KEYWORDS_BEFORE_EXPRESSION.has(previousWord);
|
|
195
|
+
if (expression) {
|
|
196
|
+
index = skipRegex(index);
|
|
197
|
+
previous = 'regex';
|
|
198
|
+
previousWord = '';
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
index += 1;
|
|
202
|
+
previous = '/';
|
|
203
|
+
previousWord = '';
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (char === '{') {
|
|
207
|
+
braceDepth += 1;
|
|
208
|
+
}
|
|
209
|
+
else if (char === '}') {
|
|
210
|
+
braceDepth -= 1;
|
|
211
|
+
if (templates.length > 0 && templates[templates.length - 1] === braceDepth) {
|
|
212
|
+
templates.pop();
|
|
213
|
+
index = skipTemplateText(index + 1);
|
|
214
|
+
previous = '`';
|
|
215
|
+
previousWord = '';
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (char === ';')
|
|
220
|
+
pendingStatement = undefined;
|
|
221
|
+
if (isIdentifierStart(char) && !isIdentifierPart(text[index - 1] ?? '')) {
|
|
222
|
+
const word = wordAt(index);
|
|
223
|
+
const afterWord = index + word.length;
|
|
224
|
+
const memberAccess = previous === '.' || previous === '?.';
|
|
225
|
+
if (!memberAccess && (word === 'import' || word === 'export' || word === 'require' || word === 'from')) {
|
|
226
|
+
const at = skipSpace(afterWord);
|
|
227
|
+
const following = text[at] ?? '';
|
|
228
|
+
if (word === 'require' || (word === 'import' && following === '(')) {
|
|
229
|
+
if (following === '(') {
|
|
230
|
+
const argument = skipSpace(at + 1);
|
|
231
|
+
const literal = literalAt(argument);
|
|
232
|
+
if (literal && text[skipSpace(literal.end)] === ')' && literal.value.length > 0) {
|
|
233
|
+
specifiers.push({ specifier: literal.value, kind: word === 'require' ? 'require' : 'dynamic' });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else if (word === 'import' && following !== '.') {
|
|
238
|
+
const literal = literalAt(at);
|
|
239
|
+
if (literal) {
|
|
240
|
+
specifiers.push({ specifier: literal.value, kind: 'static' });
|
|
241
|
+
index = literal.end;
|
|
242
|
+
previous = '"';
|
|
243
|
+
previousWord = '';
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
const nextWord = wordAt(at);
|
|
247
|
+
const typeOnly = nextWord === 'type' && /^[\s]*[{*A-Za-z_$]/.test(text.slice(at + 4, at + 6)) && wordAt(skipSpace(at + 4)) !== 'from';
|
|
248
|
+
pendingStatement = typeOnly ? 'type' : 'value';
|
|
249
|
+
}
|
|
250
|
+
else if (word === 'export') {
|
|
251
|
+
const nextWord = wordAt(at);
|
|
252
|
+
if (following === '{' || following === '*')
|
|
253
|
+
pendingStatement = 'value';
|
|
254
|
+
else if (nextWord === 'type' && /^\s*[{*]/.test(text.slice(at + 4, at + 7)))
|
|
255
|
+
pendingStatement = 'type';
|
|
256
|
+
}
|
|
257
|
+
else if (word === 'from' && pendingStatement !== undefined) {
|
|
258
|
+
const literal = literalAt(at);
|
|
259
|
+
if (literal) {
|
|
260
|
+
if (pendingStatement === 'value')
|
|
261
|
+
specifiers.push({ specifier: literal.value, kind: 'static' });
|
|
262
|
+
pendingStatement = undefined;
|
|
263
|
+
index = literal.end;
|
|
264
|
+
previous = '"';
|
|
265
|
+
previousWord = '';
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
index = afterWord;
|
|
271
|
+
previous = 'word';
|
|
272
|
+
previousWord = word;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (char !== ' ' && char !== '\t' && char !== '\n' && char !== '\r') {
|
|
276
|
+
previous = char === '?' && next === '.' ? '?.' : char;
|
|
277
|
+
if (previous === '?.')
|
|
278
|
+
index += 1;
|
|
279
|
+
previousWord = '';
|
|
280
|
+
}
|
|
281
|
+
index += 1;
|
|
282
|
+
}
|
|
283
|
+
return { specifiers, regions };
|
|
284
|
+
}
|
|
285
|
+
export const SubpathTargetSchema = z.lazy(() => z.union([
|
|
286
|
+
z.string().transform((path) => ({ kind: 'path', path })),
|
|
287
|
+
z.null().transform(() => ({ kind: 'excluded' })),
|
|
288
|
+
z.array(SubpathTargetSchema).transform((items) => ({ kind: 'list', items })),
|
|
289
|
+
z.record(z.string(), SubpathTargetSchema).transform((record) => ({ kind: 'keyed', entries: Object.entries(record) }))
|
|
290
|
+
]));
|
|
291
|
+
/** The manifest fields resolution reads. A field another tool shapes differently is no resolution evidence, not a failure. */
|
|
292
|
+
const PackageManifestSchema = z.object({
|
|
293
|
+
name: z.string().optional(),
|
|
294
|
+
main: z.string().optional().catch(undefined),
|
|
295
|
+
module: z.string().optional().catch(undefined),
|
|
296
|
+
/** Only the string form names an entry; the object form remaps files, which this walk does not follow. */
|
|
297
|
+
browser: z.string().optional().catch(undefined),
|
|
298
|
+
exports: SubpathTargetSchema.optional().catch(undefined),
|
|
299
|
+
imports: SubpathTargetSchema.optional().catch(undefined),
|
|
300
|
+
vibes: z.object({ host: z.boolean().optional() }).loose().optional()
|
|
301
|
+
});
|
|
302
|
+
export function joinPath(directory, name) {
|
|
303
|
+
return `${directory.replace(/\/+$/, '')}/${name}`;
|
|
304
|
+
}
|
|
305
|
+
export function parentPath(path) {
|
|
306
|
+
const trimmed = path.replace(/\/+$/, '');
|
|
307
|
+
const index = trimmed.lastIndexOf('/');
|
|
308
|
+
return index <= 0 ? '/' : trimmed.slice(0, index);
|
|
309
|
+
}
|
|
310
|
+
/** Resolve `.` and `..` segments of an absolute `/`-separated path. */
|
|
311
|
+
export function normalizePath(path) {
|
|
312
|
+
const out = [];
|
|
313
|
+
for (const segment of path.split('/')) {
|
|
314
|
+
if (segment === '' || segment === '.')
|
|
315
|
+
continue;
|
|
316
|
+
if (segment === '..')
|
|
317
|
+
out.pop();
|
|
318
|
+
else
|
|
319
|
+
out.push(segment);
|
|
320
|
+
}
|
|
321
|
+
return `/${out.join('/')}`;
|
|
322
|
+
}
|
|
323
|
+
export function relativeTo(root, path) {
|
|
324
|
+
const prefix = `${root.replace(/\/+$/, '')}/`;
|
|
325
|
+
if (path.startsWith(prefix))
|
|
326
|
+
return path.slice(prefix.length);
|
|
327
|
+
const rootSegments = root.split('/').filter(Boolean);
|
|
328
|
+
const pathSegments = path.split('/').filter(Boolean);
|
|
329
|
+
let shared = 0;
|
|
330
|
+
while (shared < rootSegments.length && rootSegments[shared] === pathSegments[shared])
|
|
331
|
+
shared += 1;
|
|
332
|
+
return [...rootSegments.slice(shared).map(() => '..'), ...pathSegments.slice(shared)].join('/');
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Node's own built-in module namespace (what `node:module`'s `builtinModules` lists, without
|
|
336
|
+
* internal `_` modules a bundler never sees as bare names). A bundler targeting a Node-compatible
|
|
337
|
+
* runtime treats these bare names as built-ins before any `node_modules` lookup. Which of them a
|
|
338
|
+
* provider actually supplies is the provider's declaration, never this list.
|
|
339
|
+
*/
|
|
340
|
+
export const NODE_BUILTIN_MODULES = new Set([
|
|
341
|
+
'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'console', 'constants', 'crypto', 'dgram',
|
|
342
|
+
'diagnostics_channel', 'dns', 'domain', 'events', 'fs', 'http', 'http2', 'https', 'inspector', 'module', 'net',
|
|
343
|
+
'os', 'path', 'perf_hooks', 'process', 'punycode', 'querystring', 'readline', 'repl', 'stream', 'string_decoder',
|
|
344
|
+
'sys', 'timers', 'tls', 'trace_events', 'tty', 'url', 'util', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib'
|
|
345
|
+
]);
|
|
346
|
+
const RESOLVABLE_EXTENSIONS = ['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts', '.json', '.svelte.js', '.svelte.ts'];
|
|
347
|
+
const SCANNED = /\.(m|c)?[jt]s$/;
|
|
348
|
+
/** One `exports`/`imports` target, resolved against the active conditions. `null` excludes the subpath. */
|
|
349
|
+
function conditionalTarget(target, conditions, star) {
|
|
350
|
+
switch (target.kind) {
|
|
351
|
+
case 'path':
|
|
352
|
+
return star === undefined ? target.path : target.path.split('*').join(star);
|
|
353
|
+
case 'excluded':
|
|
354
|
+
return null;
|
|
355
|
+
case 'list':
|
|
356
|
+
for (const candidate of target.items) {
|
|
357
|
+
const resolved = conditionalTarget(candidate, conditions, star);
|
|
358
|
+
if (resolved !== undefined)
|
|
359
|
+
return resolved;
|
|
360
|
+
}
|
|
361
|
+
return undefined;
|
|
362
|
+
case 'keyed':
|
|
363
|
+
for (const [condition, value] of target.entries) {
|
|
364
|
+
if (condition !== 'default' && !conditions.has(condition))
|
|
365
|
+
continue;
|
|
366
|
+
const resolved = conditionalTarget(value, conditions, star);
|
|
367
|
+
if (resolved !== undefined)
|
|
368
|
+
return resolved;
|
|
369
|
+
}
|
|
370
|
+
return undefined;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function isSubpathKey(key) {
|
|
374
|
+
return key.startsWith('.') || key.startsWith('#');
|
|
375
|
+
}
|
|
376
|
+
/** The Node subpath-map lookup shared by `exports` and `imports`: exact keys first, then the longest `*` pattern. */
|
|
377
|
+
export function resolveSubpathMap(map, subpath, conditions) {
|
|
378
|
+
if (!map)
|
|
379
|
+
return undefined;
|
|
380
|
+
if (map.kind !== 'keyed' || !map.entries.some(([key]) => isSubpathKey(key))) {
|
|
381
|
+
return subpath === '.' ? conditionalTarget(map, conditions, undefined) : undefined;
|
|
382
|
+
}
|
|
383
|
+
const exact = map.entries.find(([key]) => key === subpath);
|
|
384
|
+
if (exact)
|
|
385
|
+
return conditionalTarget(exact[1], conditions, undefined);
|
|
386
|
+
let best;
|
|
387
|
+
for (const [key, target] of map.entries) {
|
|
388
|
+
const starAt = key.indexOf('*');
|
|
389
|
+
if (starAt < 0)
|
|
390
|
+
continue;
|
|
391
|
+
const prefix = key.slice(0, starAt);
|
|
392
|
+
const suffix = key.slice(starAt + 1);
|
|
393
|
+
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix) || subpath.length < key.length - 1)
|
|
394
|
+
continue;
|
|
395
|
+
if (!best || prefix.length > best.prefixLength)
|
|
396
|
+
best = { prefixLength: prefix.length, target, star: subpath.slice(prefix.length, subpath.length - suffix.length) };
|
|
397
|
+
}
|
|
398
|
+
return best ? conditionalTarget(best.target, conditions, best.star) : undefined;
|
|
399
|
+
}
|
|
400
|
+
/** Every path a target names under any condition. */
|
|
401
|
+
function targetPaths(target) {
|
|
402
|
+
switch (target.kind) {
|
|
403
|
+
case 'path':
|
|
404
|
+
return [target.path];
|
|
405
|
+
case 'excluded':
|
|
406
|
+
return [];
|
|
407
|
+
case 'list':
|
|
408
|
+
return target.items.flatMap(targetPaths);
|
|
409
|
+
case 'keyed':
|
|
410
|
+
return target.entries.flatMap(([, value]) => targetPaths(value));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/** The export subpaths (`./consumer/plugin`) whose targets, under any condition, name `file` inside its package. */
|
|
414
|
+
export function exportSubpathsOf(info, file) {
|
|
415
|
+
const exports = info.exports;
|
|
416
|
+
if (!exports || exports.kind !== 'keyed')
|
|
417
|
+
return [];
|
|
418
|
+
const relative = `./${relativeTo(info.dir, file)}`;
|
|
419
|
+
const found = [];
|
|
420
|
+
for (const [key, value] of exports.entries) {
|
|
421
|
+
if (!key.startsWith('.'))
|
|
422
|
+
continue;
|
|
423
|
+
for (const target of targetPaths(value)) {
|
|
424
|
+
const starAt = target.indexOf('*');
|
|
425
|
+
const matches = starAt < 0
|
|
426
|
+
? target === relative
|
|
427
|
+
: relative.startsWith(target.slice(0, starAt)) && relative.endsWith(target.slice(starAt + 1));
|
|
428
|
+
if (matches) {
|
|
429
|
+
found.push(key);
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return found;
|
|
435
|
+
}
|
|
436
|
+
/** Caches over the file view: every probe the resolver makes is read once. */
|
|
437
|
+
export class ModuleResolver {
|
|
438
|
+
#files;
|
|
439
|
+
#resolution;
|
|
440
|
+
#conditions;
|
|
441
|
+
#isFile = new Map();
|
|
442
|
+
#packages = new Map();
|
|
443
|
+
#owners = new Map();
|
|
444
|
+
#real = new Map();
|
|
445
|
+
constructor(files, resolution) {
|
|
446
|
+
this.#files = files;
|
|
447
|
+
this.#resolution = resolution;
|
|
448
|
+
this.#conditions = new Set(resolution.conditions);
|
|
449
|
+
}
|
|
450
|
+
isFile(path) {
|
|
451
|
+
let cached = this.#isFile.get(path);
|
|
452
|
+
if (!cached) {
|
|
453
|
+
cached = (async () => {
|
|
454
|
+
if ((await this.#files.list(path)) !== undefined)
|
|
455
|
+
return false;
|
|
456
|
+
return (await this.#files.readText(path)) !== undefined;
|
|
457
|
+
})();
|
|
458
|
+
this.#isFile.set(path, cached);
|
|
459
|
+
}
|
|
460
|
+
return cached;
|
|
461
|
+
}
|
|
462
|
+
real(path) {
|
|
463
|
+
let cached = this.#real.get(path);
|
|
464
|
+
if (!cached) {
|
|
465
|
+
cached = (async () => (this.#files.realpath ? ((await this.#files.realpath(path)) ?? path) : path))();
|
|
466
|
+
this.#real.set(path, cached);
|
|
467
|
+
}
|
|
468
|
+
return cached;
|
|
469
|
+
}
|
|
470
|
+
/** The package whose manifest sits in `dir`, if any. */
|
|
471
|
+
packageAt(dir) {
|
|
472
|
+
let cached = this.#packages.get(dir);
|
|
473
|
+
if (!cached) {
|
|
474
|
+
cached = (async () => {
|
|
475
|
+
const manifestPath = joinPath(dir, 'package.json');
|
|
476
|
+
if (!(await this.isFile(manifestPath)))
|
|
477
|
+
return undefined;
|
|
478
|
+
const text = await this.#files.readText(manifestPath);
|
|
479
|
+
if (text === undefined)
|
|
480
|
+
return undefined;
|
|
481
|
+
const decoded = jsoncCodec.parse(text);
|
|
482
|
+
if (decoded.errorOffsets.length > 0)
|
|
483
|
+
return undefined;
|
|
484
|
+
const parsed = PackageManifestSchema.safeParse(decoded.value);
|
|
485
|
+
if (!parsed.success)
|
|
486
|
+
return undefined;
|
|
487
|
+
const manifest = parsed.data;
|
|
488
|
+
let info = {
|
|
489
|
+
dir,
|
|
490
|
+
name: manifest.name ?? dir.split('/').at(-1) ?? dir,
|
|
491
|
+
named: manifest.name !== undefined,
|
|
492
|
+
host: manifest.vibes?.host === true,
|
|
493
|
+
vibes: manifest.vibes !== undefined
|
|
494
|
+
};
|
|
495
|
+
if (manifest.exports)
|
|
496
|
+
info = { ...info, exports: manifest.exports };
|
|
497
|
+
if (manifest.imports)
|
|
498
|
+
info = { ...info, imports: manifest.imports };
|
|
499
|
+
if (manifest.main)
|
|
500
|
+
info = { ...info, main: manifest.main };
|
|
501
|
+
if (manifest.module)
|
|
502
|
+
info = { ...info, module: manifest.module };
|
|
503
|
+
if (manifest.browser)
|
|
504
|
+
info = { ...info, browser: manifest.browser };
|
|
505
|
+
return info;
|
|
506
|
+
})();
|
|
507
|
+
this.#packages.set(dir, cached);
|
|
508
|
+
}
|
|
509
|
+
return cached;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* The nearest named package that owns `path`. A nameless `package.json` (a nested
|
|
513
|
+
* `{ "type": "module" }` marker inside a published package) is not a package boundary.
|
|
514
|
+
*/
|
|
515
|
+
ownerOf(path) {
|
|
516
|
+
const dir = parentPath(path);
|
|
517
|
+
let cached = this.#owners.get(dir);
|
|
518
|
+
if (!cached) {
|
|
519
|
+
cached = (async () => {
|
|
520
|
+
const own = await this.packageAt(dir);
|
|
521
|
+
if (own?.named)
|
|
522
|
+
return own;
|
|
523
|
+
return dir === '/' ? undefined : this.ownerOf(dir);
|
|
524
|
+
})();
|
|
525
|
+
this.#owners.set(dir, cached);
|
|
526
|
+
}
|
|
527
|
+
return cached;
|
|
528
|
+
}
|
|
529
|
+
async #fileOrIndex(base) {
|
|
530
|
+
if (await this.isFile(base))
|
|
531
|
+
return this.real(base);
|
|
532
|
+
for (const extension of RESOLVABLE_EXTENSIONS) {
|
|
533
|
+
if (await this.isFile(`${base}${extension}`))
|
|
534
|
+
return this.real(`${base}${extension}`);
|
|
535
|
+
}
|
|
536
|
+
const own = await this.packageAt(base);
|
|
537
|
+
if (own) {
|
|
538
|
+
for (const field of this.#resolution.mainFields) {
|
|
539
|
+
const entry = field === 'main' ? own.main : field === 'module' ? own.module : field === 'browser' ? own.browser : undefined;
|
|
540
|
+
if (!entry)
|
|
541
|
+
continue;
|
|
542
|
+
const resolved = await this.#fileOrIndex(normalizePath(joinPath(base, entry)));
|
|
543
|
+
if (resolved)
|
|
544
|
+
return resolved;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
for (const extension of RESOLVABLE_EXTENSIONS) {
|
|
548
|
+
const index = joinPath(base, `index${extension}`);
|
|
549
|
+
if (await this.isFile(index))
|
|
550
|
+
return this.real(index);
|
|
551
|
+
}
|
|
552
|
+
return undefined;
|
|
553
|
+
}
|
|
554
|
+
async #inPackage(info, subpath) {
|
|
555
|
+
if (info.exports !== undefined) {
|
|
556
|
+
const target = resolveSubpathMap(info.exports, subpath, this.#conditions);
|
|
557
|
+
if (target === null || target === undefined)
|
|
558
|
+
return undefined;
|
|
559
|
+
const path = normalizePath(joinPath(info.dir, target));
|
|
560
|
+
return (await this.isFile(path)) ? this.real(path) : undefined;
|
|
561
|
+
}
|
|
562
|
+
return this.#fileOrIndex(subpath === '.' ? info.dir : normalizePath(joinPath(info.dir, subpath)));
|
|
563
|
+
}
|
|
564
|
+
isBuiltin(specifier) {
|
|
565
|
+
if (specifier.startsWith('node:'))
|
|
566
|
+
return specifier.slice('node:'.length);
|
|
567
|
+
const base = specifier.split('/')[0] ?? specifier;
|
|
568
|
+
const named = (name) => NODE_BUILTIN_MODULES.has(name) || this.#resolution.builtinNames.has(name);
|
|
569
|
+
return named(specifier) || named(base) ? specifier : undefined;
|
|
570
|
+
}
|
|
571
|
+
async resolve(from, raw) {
|
|
572
|
+
const specifier = raw.split(/[?#]/)[0] ?? raw;
|
|
573
|
+
if (specifier.startsWith('./') || specifier.startsWith('../') || specifier.startsWith('/')) {
|
|
574
|
+
const base = specifier.startsWith('/') ? normalizePath(specifier) : normalizePath(joinPath(parentPath(from), specifier));
|
|
575
|
+
const path = await this.#fileOrIndex(base);
|
|
576
|
+
if (!path)
|
|
577
|
+
return { kind: 'unresolved', specifier: raw };
|
|
578
|
+
const owner = await this.ownerOf(path);
|
|
579
|
+
return owner ? { kind: 'file', path, package: owner } : { kind: 'file', path };
|
|
580
|
+
}
|
|
581
|
+
const builtin = this.isBuiltin(specifier);
|
|
582
|
+
if (builtin !== undefined)
|
|
583
|
+
return { kind: 'builtin', name: builtin, specifier: raw };
|
|
584
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(specifier))
|
|
585
|
+
return { kind: 'builtin', name: specifier, specifier: raw };
|
|
586
|
+
if (specifier.startsWith('#')) {
|
|
587
|
+
const owner = await this.ownerOf(from);
|
|
588
|
+
const target = owner ? resolveSubpathMap(owner.imports, specifier, this.#conditions) : undefined;
|
|
589
|
+
if (!owner || target === null || target === undefined)
|
|
590
|
+
return { kind: 'unresolved', specifier: raw };
|
|
591
|
+
if (!target.startsWith('.'))
|
|
592
|
+
return this.resolve(from, target);
|
|
593
|
+
const path = normalizePath(joinPath(owner.dir, target));
|
|
594
|
+
return (await this.isFile(path)) ? { kind: 'file', path: await this.real(path), package: owner } : { kind: 'unresolved', specifier: raw };
|
|
595
|
+
}
|
|
596
|
+
const parts = specifier.split('/');
|
|
597
|
+
const name = specifier.startsWith('@') ? parts.slice(0, 2).join('/') : (parts[0] ?? specifier);
|
|
598
|
+
const rest = parts.slice(specifier.startsWith('@') ? 2 : 1).join('/');
|
|
599
|
+
const subpath = rest ? `./${rest}` : '.';
|
|
600
|
+
let directory = parentPath(from);
|
|
601
|
+
for (;;) {
|
|
602
|
+
const candidate = joinPath(joinPath(directory, 'node_modules'), name);
|
|
603
|
+
const found = await this.packageAt(candidate);
|
|
604
|
+
if (found) {
|
|
605
|
+
const dir = await this.real(candidate);
|
|
606
|
+
const info = dir === candidate ? found : ((await this.packageAt(dir)) ?? found);
|
|
607
|
+
const path = await this.#inPackage(info, subpath);
|
|
608
|
+
return path ? { kind: 'file', path, package: info } : { kind: 'unresolved', specifier: raw };
|
|
609
|
+
}
|
|
610
|
+
if (directory === '/')
|
|
611
|
+
return { kind: 'unresolved', specifier: raw };
|
|
612
|
+
directory = parentPath(directory);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Walk breadth-first from `entries`, so each file's recorded importer is on a shortest chain from
|
|
618
|
+
* an entry.
|
|
619
|
+
*/
|
|
620
|
+
export async function walkModuleGraph(resolver, files, entries) {
|
|
621
|
+
const reached = new Map();
|
|
622
|
+
const builtins = [];
|
|
623
|
+
const unresolved = [];
|
|
624
|
+
const edges = [];
|
|
625
|
+
const seenLeaves = new Set();
|
|
626
|
+
let frontier = [];
|
|
627
|
+
for (const entry of entries) {
|
|
628
|
+
const path = await resolver.real(normalizePath(entry));
|
|
629
|
+
const owner = await resolver.ownerOf(path);
|
|
630
|
+
frontier.push(owner ? { path, package: owner } : { path });
|
|
631
|
+
}
|
|
632
|
+
while (frontier.length > 0) {
|
|
633
|
+
const next = [];
|
|
634
|
+
for (const item of frontier) {
|
|
635
|
+
if (reached.has(item.path))
|
|
636
|
+
continue;
|
|
637
|
+
const text = await files.readText(item.path);
|
|
638
|
+
if (text === undefined)
|
|
639
|
+
continue;
|
|
640
|
+
const scanned = SCANNED.test(item.path) ? scanModule(text) : { specifiers: [], regions: [] };
|
|
641
|
+
let file = { path: item.path, bytes: utf8Bytes(text), regions: scanned.regions };
|
|
642
|
+
if (item.package)
|
|
643
|
+
file = { ...file, package: item.package };
|
|
644
|
+
if (item.importer)
|
|
645
|
+
file = { ...file, importer: item.importer };
|
|
646
|
+
if (item.specifier)
|
|
647
|
+
file = { ...file, specifier: item.specifier };
|
|
648
|
+
reached.set(item.path, file);
|
|
649
|
+
for (const { specifier, kind } of scanned.specifiers) {
|
|
650
|
+
const resolved = await resolver.resolve(item.path, specifier);
|
|
651
|
+
if (resolved.kind === 'file') {
|
|
652
|
+
edges.push({ importer: item.path, specifier, path: resolved.path, kind });
|
|
653
|
+
if (!reached.has(resolved.path)) {
|
|
654
|
+
next.push(resolved.package ? { path: resolved.path, importer: item.path, specifier, package: resolved.package } : { path: resolved.path, importer: item.path, specifier });
|
|
655
|
+
}
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
const key = `${resolved.kind}:${specifier}:${item.path}`;
|
|
659
|
+
if (seenLeaves.has(key))
|
|
660
|
+
continue;
|
|
661
|
+
seenLeaves.add(key);
|
|
662
|
+
const leaf = { specifier, name: resolved.kind === 'builtin' ? resolved.name : specifier, importer: item.path };
|
|
663
|
+
if (resolved.kind === 'builtin')
|
|
664
|
+
builtins.push(leaf);
|
|
665
|
+
else
|
|
666
|
+
unresolved.push(leaf);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
frontier = next;
|
|
670
|
+
}
|
|
671
|
+
// Only a static edge makes a module part of the bundle the Worker instantiates;
|
|
672
|
+
// a loader thunk's implementation stays enumerable but is refused at resolution.
|
|
673
|
+
const staticByImporter = new Map();
|
|
674
|
+
for (const edge of edges) {
|
|
675
|
+
if (edge.kind !== 'static')
|
|
676
|
+
continue;
|
|
677
|
+
const list = staticByImporter.get(edge.importer) ?? [];
|
|
678
|
+
list.push(edge.path);
|
|
679
|
+
staticByImporter.set(edge.importer, list);
|
|
680
|
+
}
|
|
681
|
+
const staticReachable = new Set();
|
|
682
|
+
const staticFrontier = await Promise.all(entries.map((entry) => resolver.real(normalizePath(entry))));
|
|
683
|
+
while (staticFrontier.length > 0) {
|
|
684
|
+
const path = staticFrontier.pop();
|
|
685
|
+
if (path === undefined || staticReachable.has(path))
|
|
686
|
+
continue;
|
|
687
|
+
staticReachable.add(path);
|
|
688
|
+
for (const next of staticByImporter.get(path) ?? [])
|
|
689
|
+
staticFrontier.push(next);
|
|
690
|
+
}
|
|
691
|
+
return { files: reached, builtins, unresolved, edges, staticReachable };
|
|
692
|
+
}
|
|
693
|
+
/** The importing chain of `path`, entry first and `path` last. */
|
|
694
|
+
export function chainOf(graph, path) {
|
|
695
|
+
const chain = [path];
|
|
696
|
+
const seen = new Set(chain);
|
|
697
|
+
let current = graph.files.get(path)?.importer;
|
|
698
|
+
while (current !== undefined && !seen.has(current)) {
|
|
699
|
+
chain.push(current);
|
|
700
|
+
seen.add(current);
|
|
701
|
+
current = graph.files.get(current)?.importer;
|
|
702
|
+
}
|
|
703
|
+
return chain.reverse();
|
|
704
|
+
}
|
|
705
|
+
//# sourceMappingURL=deployment-graph.js.map
|