@nifrajs/web 4.0.2 → 5.1.0
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/README.md +19 -0
- package/dist/build-vite.d.ts +19 -0
- package/dist/build-vite.d.ts.map +1 -1
- package/dist/build-vite.js +31 -10
- package/dist/build-vite.js.map +1 -1
- package/dist/build.d.ts +8 -10
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +90 -31
- package/dist/build.js.map +1 -1
- package/dist/cdn.d.ts +8 -0
- package/dist/cdn.d.ts.map +1 -1
- package/dist/cdn.js +14 -15
- package/dist/cdn.js.map +1 -1
- package/dist/client.d.ts +6 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +46 -18
- package/dist/client.js.map +1 -1
- package/dist/deferred.d.ts +2 -2
- package/dist/deferred.d.ts.map +1 -1
- package/dist/deferred.js +28 -7
- package/dist/deferred.js.map +1 -1
- package/dist/dev-feed.d.ts.map +1 -1
- package/dist/dev-feed.js +24 -5
- package/dist/dev-feed.js.map +1 -1
- package/dist/dev-port.d.ts +3 -2
- package/dist/dev-port.d.ts.map +1 -1
- package/dist/dev-port.js +2 -6
- package/dist/dev-port.js.map +1 -1
- package/dist/dev-session.d.ts.map +1 -1
- package/dist/dev-session.js +4 -14
- package/dist/dev-session.js.map +1 -1
- package/dist/dev.d.ts +7 -17
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +13 -1
- package/dist/dev.js.map +1 -1
- package/dist/draft.d.ts +8 -5
- package/dist/draft.d.ts.map +1 -1
- package/dist/draft.js +30 -13
- package/dist/draft.js.map +1 -1
- package/dist/fonts-google.d.ts.map +1 -1
- package/dist/fonts-google.js +7 -0
- package/dist/fonts-google.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/internal/codegen.d.ts +1 -0
- package/dist/internal/codegen.d.ts.map +1 -1
- package/dist/internal/codegen.js +56 -29
- package/dist/internal/codegen.js.map +1 -1
- package/dist/internal/disposable-dir.d.ts +8 -0
- package/dist/internal/disposable-dir.d.ts.map +1 -0
- package/dist/internal/disposable-dir.js +25 -0
- package/dist/internal/disposable-dir.js.map +1 -0
- package/dist/internal/entry-chunks.d.ts +9 -0
- package/dist/internal/entry-chunks.d.ts.map +1 -0
- package/dist/internal/entry-chunks.js +15 -0
- package/dist/internal/entry-chunks.js.map +1 -0
- package/dist/internal/evidence-traversal.d.ts +12 -0
- package/dist/internal/evidence-traversal.d.ts.map +1 -0
- package/dist/internal/evidence-traversal.js +48 -0
- package/dist/internal/evidence-traversal.js.map +1 -0
- package/dist/internal/head-merge.d.ts +6 -0
- package/dist/internal/head-merge.d.ts.map +1 -1
- package/dist/internal/head-merge.js +9 -0
- package/dist/internal/head-merge.js.map +1 -1
- package/dist/internal/js-string.d.ts +2 -0
- package/dist/internal/js-string.d.ts.map +1 -1
- package/dist/internal/js-string.js +5 -1
- package/dist/internal/js-string.js.map +1 -1
- package/dist/internal/mount-shadow.js +1 -1
- package/dist/internal/mount-shadow.js.map +1 -1
- package/dist/internal/output-guard.d.ts +7 -0
- package/dist/internal/output-guard.d.ts.map +1 -1
- package/dist/internal/output-guard.js +80 -8
- package/dist/internal/output-guard.js.map +1 -1
- package/dist/internal/package-entries.d.ts +34 -0
- package/dist/internal/package-entries.d.ts.map +1 -0
- package/dist/internal/package-entries.js +324 -0
- package/dist/internal/package-entries.js.map +1 -0
- package/dist/internal/page-execution.d.ts +6 -0
- package/dist/internal/page-execution.d.ts.map +1 -1
- package/dist/internal/page-execution.js +437 -114
- package/dist/internal/page-execution.js.map +1 -1
- package/dist/internal/parity.d.ts.map +1 -1
- package/dist/internal/parity.js +15 -2
- package/dist/internal/parity.js.map +1 -1
- package/dist/internal/private-env.d.ts +8 -0
- package/dist/internal/private-env.d.ts.map +1 -1
- package/dist/internal/private-env.js +25 -10
- package/dist/internal/private-env.js.map +1 -1
- package/dist/internal/progressive-cookies.d.ts +14 -0
- package/dist/internal/progressive-cookies.d.ts.map +1 -0
- package/dist/internal/progressive-cookies.js +43 -0
- package/dist/internal/progressive-cookies.js.map +1 -0
- package/dist/internal/public-env.d.ts +2 -0
- package/dist/internal/public-env.d.ts.map +1 -0
- package/dist/internal/public-env.js +13 -0
- package/dist/internal/public-env.js.map +1 -0
- package/dist/internal/render-document.d.ts +5 -44
- package/dist/internal/render-document.d.ts.map +1 -1
- package/dist/internal/render-document.js +51 -63
- package/dist/internal/render-document.js.map +1 -1
- package/dist/internal/response-controls.d.ts +2 -0
- package/dist/internal/response-controls.d.ts.map +1 -1
- package/dist/internal/response-controls.js +26 -16
- package/dist/internal/response-controls.js.map +1 -1
- package/dist/internal/revive-dates.d.ts +16 -0
- package/dist/internal/revive-dates.d.ts.map +1 -0
- package/dist/internal/revive-dates.js +32 -0
- package/dist/internal/revive-dates.js.map +1 -0
- package/dist/internal/route-path.d.ts +14 -0
- package/dist/internal/route-path.d.ts.map +1 -0
- package/dist/internal/route-path.js +19 -0
- package/dist/internal/route-path.js.map +1 -0
- package/dist/internal/secret-scan.d.ts.map +1 -1
- package/dist/internal/secret-scan.js +190 -20
- package/dist/internal/secret-scan.js.map +1 -1
- package/dist/internal/server-boundary.d.ts.map +1 -1
- package/dist/internal/server-boundary.js +33 -5
- package/dist/internal/server-boundary.js.map +1 -1
- package/dist/internal/web-app.d.ts +25 -18
- package/dist/internal/web-app.d.ts.map +1 -1
- package/dist/internal/web-app.js +81 -24
- package/dist/internal/web-app.js.map +1 -1
- package/dist/internal/wire-date.d.ts +3 -0
- package/dist/internal/wire-date.d.ts.map +1 -0
- package/dist/internal/wire-date.js +14 -0
- package/dist/internal/wire-date.js.map +1 -0
- package/dist/internal/without-query.d.ts +4 -0
- package/dist/internal/without-query.d.ts.map +1 -0
- package/dist/internal/without-query.js +9 -0
- package/dist/internal/without-query.js.map +1 -0
- package/dist/internal/zone-graph.d.ts +4 -0
- package/dist/internal/zone-graph.d.ts.map +1 -1
- package/dist/internal/zone-graph.js +71 -20
- package/dist/internal/zone-graph.js.map +1 -1
- package/dist/isr.d.ts +59 -3
- package/dist/isr.d.ts.map +1 -1
- package/dist/isr.js +311 -41
- package/dist/isr.js.map +1 -1
- package/dist/llms-txt.d.ts +2 -0
- package/dist/llms-txt.d.ts.map +1 -1
- package/dist/llms-txt.js +29 -3
- package/dist/llms-txt.js.map +1 -1
- package/dist/manifest.d.ts +37 -4
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +4 -0
- package/dist/manifest.js.map +1 -1
- package/dist/open-resolved.d.ts +18 -0
- package/dist/open-resolved.d.ts.map +1 -0
- package/dist/open-resolved.js +62 -0
- package/dist/open-resolved.js.map +1 -0
- package/dist/plugins/kit.d.ts +1 -0
- package/dist/plugins/kit.d.ts.map +1 -1
- package/dist/plugins/kit.js +26 -11
- package/dist/plugins/kit.js.map +1 -1
- package/dist/plugins/vite-leak-guard.d.ts +9 -1
- package/dist/plugins/vite-leak-guard.d.ts.map +1 -1
- package/dist/plugins/vite-leak-guard.js +84 -7
- package/dist/plugins/vite-leak-guard.js.map +1 -1
- package/dist/plugins/vite-zone-guard.d.ts.map +1 -1
- package/dist/plugins/vite-zone-guard.js +17 -21
- package/dist/plugins/vite-zone-guard.js.map +1 -1
- package/dist/plugins/zone-guard.d.ts.map +1 -1
- package/dist/plugins/zone-guard.js +44 -3
- package/dist/plugins/zone-guard.js.map +1 -1
- package/dist/prerender.d.ts +5 -1
- package/dist/prerender.d.ts.map +1 -1
- package/dist/prerender.js +41 -19
- package/dist/prerender.js.map +1 -1
- package/dist/public-dir.d.ts +8 -1
- package/dist/public-dir.d.ts.map +1 -1
- package/dist/public-dir.js +17 -6
- package/dist/public-dir.js.map +1 -1
- package/dist/query.d.ts +13 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +89 -26
- package/dist/query.js.map +1 -1
- package/dist/render-seam.d.ts +25 -2
- package/dist/render-seam.d.ts.map +1 -1
- package/dist/render-seam.js +1 -0
- package/dist/render-seam.js.map +1 -1
- package/dist/route-types.d.ts.map +1 -1
- package/dist/route-types.js +20 -9
- package/dist/route-types.js.map +1 -1
- package/dist/router.d.ts +9 -2
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +47 -50
- package/dist/router.js.map +1 -1
- package/dist/seo.d.ts +49 -0
- package/dist/seo.d.ts.map +1 -0
- package/dist/seo.js +48 -0
- package/dist/seo.js.map +1 -0
- package/dist/server-components/build-info.d.ts +3 -0
- package/dist/server-components/build-info.d.ts.map +1 -0
- package/dist/server-components/build-info.js +7 -0
- package/dist/server-components/build-info.js.map +1 -0
- package/dist/server-components/build-target.d.ts +12 -0
- package/dist/server-components/build-target.d.ts.map +1 -0
- package/dist/server-components/build-target.js +153 -0
- package/dist/server-components/build-target.js.map +1 -0
- package/dist/server-components/build.d.ts +24 -0
- package/dist/server-components/build.d.ts.map +1 -0
- package/dist/server-components/build.js +366 -0
- package/dist/server-components/build.js.map +1 -0
- package/dist/server-components/bundle-proof.d.ts +3 -0
- package/dist/server-components/bundle-proof.d.ts.map +1 -0
- package/dist/server-components/bundle-proof.js +23 -0
- package/dist/server-components/bundle-proof.js.map +1 -0
- package/dist/server-components/client.d.ts +46 -0
- package/dist/server-components/client.d.ts.map +1 -0
- package/dist/server-components/client.js +594 -0
- package/dist/server-components/client.js.map +1 -0
- package/dist/server-components/definition.d.ts +11 -0
- package/dist/server-components/definition.d.ts.map +1 -0
- package/dist/server-components/definition.js +94 -0
- package/dist/server-components/definition.js.map +1 -0
- package/dist/server-components/dev-http.d.ts +5 -0
- package/dist/server-components/dev-http.d.ts.map +1 -0
- package/dist/server-components/dev-http.js +71 -0
- package/dist/server-components/dev-http.js.map +1 -0
- package/dist/server-components/error.d.ts +9 -0
- package/dist/server-components/error.d.ts.map +1 -0
- package/dist/server-components/error.js +24 -0
- package/dist/server-components/error.js.map +1 -0
- package/dist/server-components/frames.d.ts +7 -0
- package/dist/server-components/frames.d.ts.map +1 -0
- package/dist/server-components/frames.js +169 -0
- package/dist/server-components/frames.js.map +1 -0
- package/dist/server-components/html-policy.d.ts +6 -0
- package/dist/server-components/html-policy.d.ts.map +1 -0
- package/dist/server-components/html-policy.js +75 -0
- package/dist/server-components/html-policy.js.map +1 -0
- package/dist/server-components/html.d.ts +4 -0
- package/dist/server-components/html.d.ts.map +1 -0
- package/dist/server-components/html.js +67 -0
- package/dist/server-components/html.js.map +1 -0
- package/dist/server-components/islands.d.ts +44 -0
- package/dist/server-components/islands.d.ts.map +1 -0
- package/dist/server-components/islands.js +42 -0
- package/dist/server-components/islands.js.map +1 -0
- package/dist/server-components/native.d.ts +4 -0
- package/dist/server-components/native.d.ts.map +1 -0
- package/dist/server-components/native.js +81 -0
- package/dist/server-components/native.js.map +1 -0
- package/dist/server-components/portal.d.ts +6 -0
- package/dist/server-components/portal.d.ts.map +1 -0
- package/dist/server-components/portal.js +35 -0
- package/dist/server-components/portal.js.map +1 -0
- package/dist/server-components/props.d.ts +3 -0
- package/dist/server-components/props.d.ts.map +1 -0
- package/dist/server-components/props.js +14 -0
- package/dist/server-components/props.js.map +1 -0
- package/dist/server-components/protocol.d.ts +44 -0
- package/dist/server-components/protocol.d.ts.map +1 -0
- package/dist/server-components/protocol.js +139 -0
- package/dist/server-components/protocol.js.map +1 -0
- package/dist/server-components/range.d.ts +24 -0
- package/dist/server-components/range.d.ts.map +1 -0
- package/dist/server-components/range.js +263 -0
- package/dist/server-components/range.js.map +1 -0
- package/dist/server-components/registry.d.ts +6 -0
- package/dist/server-components/registry.d.ts.map +1 -0
- package/dist/server-components/registry.js +30 -0
- package/dist/server-components/registry.js.map +1 -0
- package/dist/server-components/response.d.ts +4 -0
- package/dist/server-components/response.d.ts.map +1 -0
- package/dist/server-components/response.js +32 -0
- package/dist/server-components/response.js.map +1 -0
- package/dist/server-components/router-integration.d.ts +9 -0
- package/dist/server-components/router-integration.d.ts.map +1 -0
- package/dist/server-components/router-integration.js +29 -0
- package/dist/server-components/router-integration.js.map +1 -0
- package/dist/server-components/runtime.d.ts +14 -0
- package/dist/server-components/runtime.d.ts.map +1 -0
- package/dist/server-components/runtime.js +276 -0
- package/dist/server-components/runtime.js.map +1 -0
- package/dist/server-components/scheduler.d.ts +14 -0
- package/dist/server-components/scheduler.d.ts.map +1 -0
- package/dist/server-components/scheduler.js +74 -0
- package/dist/server-components/scheduler.js.map +1 -0
- package/dist/server-components/schema.d.ts +4 -0
- package/dist/server-components/schema.d.ts.map +1 -0
- package/dist/server-components/schema.js +77 -0
- package/dist/server-components/schema.js.map +1 -0
- package/dist/server-components/server-entry.d.ts +12 -0
- package/dist/server-components/server-entry.d.ts.map +1 -0
- package/dist/server-components/server-entry.js +90 -0
- package/dist/server-components/server-entry.js.map +1 -0
- package/dist/server-components/source.d.ts +15 -0
- package/dist/server-components/source.d.ts.map +1 -0
- package/dist/server-components/source.js +269 -0
- package/dist/server-components/source.js.map +1 -0
- package/dist/server-components/state.d.ts +4 -0
- package/dist/server-components/state.d.ts.map +1 -0
- package/dist/server-components/state.js +123 -0
- package/dist/server-components/state.js.map +1 -0
- package/dist/server-components/stream.d.ts +6 -0
- package/dist/server-components/stream.d.ts.map +1 -0
- package/dist/server-components/stream.js +70 -0
- package/dist/server-components/stream.js.map +1 -0
- package/dist/server-components/trusted-html.d.ts +3 -0
- package/dist/server-components/trusted-html.d.ts.map +1 -0
- package/dist/server-components/trusted-html.js +14 -0
- package/dist/server-components/trusted-html.js.map +1 -0
- package/dist/server-components/types.d.ts +107 -0
- package/dist/server-components/types.d.ts.map +1 -0
- package/dist/server-components/types.js +2 -0
- package/dist/server-components/types.js.map +1 -0
- package/dist/server-components/typescript.d.ts +11 -0
- package/dist/server-components/typescript.d.ts.map +1 -0
- package/dist/server-components/typescript.js +28 -0
- package/dist/server-components/typescript.js.map +1 -0
- package/dist/server-components/value.d.ts +5 -0
- package/dist/server-components/value.d.ts.map +1 -0
- package/dist/server-components/value.js +77 -0
- package/dist/server-components/value.js.map +1 -0
- package/dist/server-components/vite.d.ts +12 -0
- package/dist/server-components/vite.d.ts.map +1 -0
- package/dist/server-components/vite.js +197 -0
- package/dist/server-components/vite.js.map +1 -0
- package/dist/server-components.d.ts +5 -0
- package/dist/server-components.d.ts.map +1 -0
- package/dist/server-components.js +4 -0
- package/dist/server-components.js.map +1 -0
- package/dist/service-worker.d.ts +8 -1
- package/dist/service-worker.d.ts.map +1 -1
- package/dist/service-worker.js +20 -6
- package/dist/service-worker.js.map +1 -1
- package/dist/vite.d.ts +12 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +7 -1
- package/dist/vite.js.map +1 -1
- package/dist/zones.d.ts +64 -2
- package/dist/zones.d.ts.map +1 -1
- package/dist/zones.js +331 -28
- package/dist/zones.js.map +1 -1
- package/package.json +102 -4
- package/src/build-vite.ts +31 -9
- package/src/build.ts +109 -31
- package/src/cdn.ts +18 -12
- package/src/client.ts +48 -17
- package/src/deferred.ts +27 -9
- package/src/dev-feed.ts +24 -5
- package/src/dev-port.ts +4 -10
- package/src/dev-session.ts +4 -13
- package/src/dev.ts +29 -1
- package/src/draft.ts +35 -14
- package/src/fonts-google.ts +10 -0
- package/src/index.ts +5 -6
- package/src/internal/codegen.ts +60 -29
- package/src/internal/disposable-dir.ts +24 -0
- package/src/internal/entry-chunks.ts +18 -0
- package/src/internal/evidence-traversal.ts +57 -0
- package/src/internal/head-merge.ts +16 -0
- package/src/internal/js-string.ts +6 -1
- package/src/internal/mount-shadow.ts +1 -1
- package/src/internal/output-guard.ts +88 -7
- package/src/internal/package-entries.ts +331 -0
- package/src/internal/page-execution.ts +573 -114
- package/src/internal/parity.ts +15 -2
- package/src/internal/private-env.ts +27 -13
- package/src/internal/progressive-cookies.ts +60 -0
- package/src/internal/public-env.ts +14 -0
- package/src/internal/render-document.ts +66 -89
- package/src/internal/response-controls.ts +31 -14
- package/src/internal/revive-dates.ts +35 -0
- package/src/internal/route-path.ts +24 -0
- package/src/internal/secret-scan.ts +190 -18
- package/src/internal/server-boundary.ts +29 -5
- package/src/internal/web-app.ts +126 -42
- package/src/internal/wire-date.ts +16 -0
- package/src/internal/without-query.ts +8 -0
- package/src/internal/zone-graph.ts +78 -25
- package/src/isr.ts +364 -45
- package/src/llms-txt.ts +32 -3
- package/src/manifest.ts +38 -4
- package/src/open-resolved.ts +64 -0
- package/src/plugins/kit.ts +31 -11
- package/src/plugins/vite-leak-guard.ts +104 -8
- package/src/plugins/vite-zone-guard.ts +21 -19
- package/src/plugins/zone-guard.ts +41 -2
- package/src/prerender.ts +39 -18
- package/src/public-dir.ts +27 -8
- package/src/query.ts +107 -26
- package/src/render-seam.ts +30 -2
- package/src/route-types.ts +34 -7
- package/src/router.ts +66 -59
- package/src/seo.ts +68 -0
- package/src/server-components/build-info.ts +11 -0
- package/src/server-components/build-target.ts +194 -0
- package/src/server-components/build.ts +419 -0
- package/src/server-components/bundle-proof.ts +33 -0
- package/src/server-components/client.ts +663 -0
- package/src/server-components/definition.ts +125 -0
- package/src/server-components/dev-http.ts +75 -0
- package/src/server-components/error.ts +24 -0
- package/src/server-components/frames.ts +181 -0
- package/src/server-components/html-policy.ts +94 -0
- package/src/server-components/html.ts +81 -0
- package/src/server-components/islands.ts +111 -0
- package/src/server-components/native.ts +101 -0
- package/src/server-components/portal.ts +42 -0
- package/src/server-components/props.ts +19 -0
- package/src/server-components/protocol.ts +167 -0
- package/src/server-components/range.ts +313 -0
- package/src/server-components/registry.ts +34 -0
- package/src/server-components/response.ts +44 -0
- package/src/server-components/router-integration.ts +40 -0
- package/src/server-components/runtime.ts +376 -0
- package/src/server-components/scheduler.ts +84 -0
- package/src/server-components/schema.ts +69 -0
- package/src/server-components/server-entry.ts +98 -0
- package/src/server-components/source.ts +324 -0
- package/src/server-components/state.ts +143 -0
- package/src/server-components/stream.ts +71 -0
- package/src/server-components/trusted-html.ts +21 -0
- package/src/server-components/types.ts +138 -0
- package/src/server-components/typescript.ts +39 -0
- package/src/server-components/value.ts +82 -0
- package/src/server-components/vite.ts +242 -0
- package/src/server-components.ts +32 -0
- package/src/service-worker.ts +24 -7
- package/src/vite.ts +8 -1
- package/src/zones.ts +418 -32
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-entry package sides: `"nifra": { "environment": { ".": "backend", "./react": "frontend" } }`.
|
|
3
|
+
*
|
|
4
|
+
* An import names an entry, and that entry's side decides it. A path names no entry, so a file is owned
|
|
5
|
+
* by every mapped entry that reaches it inside the package: the entry's targets under any export
|
|
6
|
+
* condition, followed through relative imports. A stage that sees only paths decides by those owners;
|
|
7
|
+
* which entry an import may name is decided where the import is written, from its specifier.
|
|
8
|
+
*/
|
|
9
|
+
import { readdirSync, readFileSync, realpathSync, statSync } from "node:fs"
|
|
10
|
+
import { dirname, extname, join, relative } from "node:path"
|
|
11
|
+
import type { PackageEnvironment } from "../zones.ts"
|
|
12
|
+
import { type Token, tokenize } from "./private-env.ts"
|
|
13
|
+
import { withoutQuery } from "./without-query.ts"
|
|
14
|
+
|
|
15
|
+
export type EnvironmentDeclaration =
|
|
16
|
+
| { readonly kind: "none" }
|
|
17
|
+
| { readonly kind: "package"; readonly side: PackageEnvironment }
|
|
18
|
+
| { readonly kind: "entries"; readonly entries: Readonly<Record<string, PackageEnvironment>> }
|
|
19
|
+
| { readonly kind: "invalid"; readonly problem: string }
|
|
20
|
+
|
|
21
|
+
const SIDES: ReadonlySet<string> = new Set(["frontend", "backend", "shared", "library"])
|
|
22
|
+
const isSide = (value: unknown): value is PackageEnvironment =>
|
|
23
|
+
typeof value === "string" && SIDES.has(value)
|
|
24
|
+
|
|
25
|
+
/** A manifest's `nifra.environment`. A string naming no side declares nothing, as it always has. */
|
|
26
|
+
export function parseEnvironment(value: unknown): EnvironmentDeclaration {
|
|
27
|
+
if (isSide(value)) return { kind: "package", side: value }
|
|
28
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return { kind: "none" }
|
|
29
|
+
const entries: Record<string, PackageEnvironment> = {}
|
|
30
|
+
for (const [key, side] of Object.entries(value)) {
|
|
31
|
+
if (key !== "." && !key.startsWith("./"))
|
|
32
|
+
return {
|
|
33
|
+
kind: "invalid",
|
|
34
|
+
problem: `key "${key}" must be "." or a subpath starting with "./"`,
|
|
35
|
+
}
|
|
36
|
+
if (key.indexOf("*") !== key.lastIndexOf("*"))
|
|
37
|
+
return { kind: "invalid", problem: `key "${key}" may hold one "*"` }
|
|
38
|
+
if (!isSide(side))
|
|
39
|
+
return {
|
|
40
|
+
kind: "invalid",
|
|
41
|
+
problem: `"${key}" must be one of frontend, backend, shared, library`,
|
|
42
|
+
}
|
|
43
|
+
entries[key] = side
|
|
44
|
+
}
|
|
45
|
+
return Object.keys(entries).length === 0
|
|
46
|
+
? {
|
|
47
|
+
kind: "invalid",
|
|
48
|
+
problem: 'maps no entry; give each export subpath (".", "./react") a side',
|
|
49
|
+
}
|
|
50
|
+
: { kind: "entries", entries }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The mapped key that decides `subpath`: the exact key, else the `*` pattern with the longest prefix,
|
|
55
|
+
* then the longest key, where `*` matches at least one character - as Node matches `exports`.
|
|
56
|
+
*/
|
|
57
|
+
export function entryKey(
|
|
58
|
+
entries: Readonly<Record<string, PackageEnvironment>>,
|
|
59
|
+
subpath: string,
|
|
60
|
+
): string | undefined {
|
|
61
|
+
if (Object.hasOwn(entries, subpath)) return subpath
|
|
62
|
+
let best: string | undefined
|
|
63
|
+
for (const key of Object.keys(entries)) {
|
|
64
|
+
const star = key.indexOf("*")
|
|
65
|
+
if (star === -1 || subpath.length < key.length) continue
|
|
66
|
+
if (!subpath.startsWith(key.slice(0, star)) || !subpath.endsWith(key.slice(star + 1))) continue
|
|
67
|
+
const bestStar = best?.indexOf("*") ?? -1
|
|
68
|
+
if (best === undefined || star > bestStar || (star === bestStar && key.length > best.length))
|
|
69
|
+
best = key
|
|
70
|
+
}
|
|
71
|
+
return best
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface EntryOwnership {
|
|
75
|
+
/** Each file a mapped entry reaches, by real path, with the sides of every entry that reaches it. */
|
|
76
|
+
readonly owners: ReadonlyMap<string, ReadonlySet<PackageEnvironment>>
|
|
77
|
+
/** Export subpaths the map gives no side. */
|
|
78
|
+
readonly unmapped: readonly string[]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const isFile = (path: string): boolean =>
|
|
82
|
+
statSync(path, { throwIfNoEntry: false })?.isFile() ?? false
|
|
83
|
+
|
|
84
|
+
const real = (path: string): string => {
|
|
85
|
+
try {
|
|
86
|
+
return realpathSync.native(path).replaceAll("\\", "/")
|
|
87
|
+
} catch {
|
|
88
|
+
return path.replaceAll("\\", "/")
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const SCRIPT = /\.(?:[cm]?[jt]sx?|svelte|vue)$/
|
|
93
|
+
const STYLESHEET = /\.(?:css|scss|sass|less|styl)$/
|
|
94
|
+
const DECLARATION = /\.d\.[cm]?ts$/
|
|
95
|
+
const PROBE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"]
|
|
96
|
+
/** A TypeScript source imports its sibling by the extension it compiles to. */
|
|
97
|
+
const SOURCE_TWINS: Readonly<Record<string, readonly string[]>> = {
|
|
98
|
+
".js": [".ts", ".tsx"],
|
|
99
|
+
".jsx": [".tsx"],
|
|
100
|
+
".mjs": [".mts"],
|
|
101
|
+
".cjs": [".cts"],
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function probe(base: string): string | undefined {
|
|
105
|
+
if (isFile(base)) return base
|
|
106
|
+
const extension = extname(base)
|
|
107
|
+
for (const twin of SOURCE_TWINS[extension] ?? []) {
|
|
108
|
+
const candidate = `${base.slice(0, -extension.length)}${twin}`
|
|
109
|
+
if (isFile(candidate)) return candidate
|
|
110
|
+
}
|
|
111
|
+
for (const candidate of PROBE_EXTENSIONS.map((ext) => `${base}${ext}`)) {
|
|
112
|
+
if (isFile(candidate)) return candidate
|
|
113
|
+
}
|
|
114
|
+
for (const candidate of PROBE_EXTENSIONS.map((ext) => join(base, `index${ext}`))) {
|
|
115
|
+
if (isFile(candidate)) return candidate
|
|
116
|
+
}
|
|
117
|
+
return undefined
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const CLAUSE_PUNCT: ReadonlySet<string> = new Set(["{", "}", ",", "*"])
|
|
121
|
+
const isPunct = (token: Token | undefined, value: string): boolean =>
|
|
122
|
+
token?.kind === "punct" && token.value === value
|
|
123
|
+
const isId = (token: Token | undefined, value: string): boolean =>
|
|
124
|
+
token?.kind === "id" && token.value === value
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Whether the `import`/`export` clause ending at the `from` token `at` binds only types: `import type`,
|
|
128
|
+
* `export type`, or a `{ }` list whose every specifier is `type`. Such an edge grants no ownership - a
|
|
129
|
+
* backend file a frontend entry merely types against stays backend. `import { type A }` survives as
|
|
130
|
+
* `import {}` under Vite with `verbatimModuleSyntax`; dropping it then fails closed, since the guard
|
|
131
|
+
* judges that load by the file's remaining owners.
|
|
132
|
+
*/
|
|
133
|
+
function typeOnlyClause(tokens: readonly Token[], at: number): boolean {
|
|
134
|
+
let start = at - 1
|
|
135
|
+
for (; start >= 0; start--) {
|
|
136
|
+
const token = tokens[start]
|
|
137
|
+
if (isId(token, "import") || isId(token, "export")) break
|
|
138
|
+
if (token?.kind !== "id" && !(token?.kind === "punct" && CLAUSE_PUNCT.has(token.value)))
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
if (start < 0) return false
|
|
142
|
+
const clause = tokens.slice(start + 1, at)
|
|
143
|
+
// `import type from "./x"` and `import type, { a } from` bind a default import named `type`.
|
|
144
|
+
if (isId(clause[0], "type")) return clause.length > 1 && !isPunct(clause[1], ",")
|
|
145
|
+
if (!isPunct(clause[0], "{") || !isPunct(clause.at(-1), "}")) return false
|
|
146
|
+
const specifiers: Token[][] = [[]]
|
|
147
|
+
for (const token of clause.slice(1, -1)) {
|
|
148
|
+
if (isPunct(token, ",")) specifiers.push([])
|
|
149
|
+
else specifiers.at(-1)?.push(token)
|
|
150
|
+
}
|
|
151
|
+
const named = specifiers.filter((specifier) => specifier.length > 0)
|
|
152
|
+
// `{ type as x }` imports a value named `type`; `{ type A }` and `{ type A as B }` import types.
|
|
153
|
+
return (
|
|
154
|
+
named.length > 0 &&
|
|
155
|
+
named.every(
|
|
156
|
+
(specifier) =>
|
|
157
|
+
isId(specifier[0], "type") &&
|
|
158
|
+
(specifier.length === 2 || (specifier.length === 4 && isId(specifier[2], "as"))),
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** The relative specifiers a module loads: imports, re-exports, `import()`s, `require`s and
|
|
164
|
+
* `new URL()`s (a worker or an asset beside it). A clause binding only types loads nothing. */
|
|
165
|
+
function relativeImports(code: string): string[] {
|
|
166
|
+
const tokens = tokenize(code)
|
|
167
|
+
const found: string[] = []
|
|
168
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
169
|
+
const token = tokens[i]
|
|
170
|
+
if (token?.kind !== "id") continue
|
|
171
|
+
const previous = tokens[i - 1]
|
|
172
|
+
if (previous?.kind === "punct" && previous.value === ".") continue
|
|
173
|
+
let next = tokens[i + 1]
|
|
174
|
+
const call = next?.kind === "punct" && next.value === "("
|
|
175
|
+
const url = token.value === "URL" && previous?.kind === "id" && previous.value === "new"
|
|
176
|
+
if (token.value === "require" || url || (token.value === "import" && call)) {
|
|
177
|
+
if (!call) continue
|
|
178
|
+
next = tokens[i + 2]
|
|
179
|
+
} else if (token.value !== "from" && token.value !== "import") continue
|
|
180
|
+
if (next?.kind !== "string" || !/^\.\.?\//.test(next.value)) continue
|
|
181
|
+
if (token.value === "from" && typeOnlyClause(tokens, i)) continue
|
|
182
|
+
found.push(next.value)
|
|
183
|
+
}
|
|
184
|
+
return found
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** What a stylesheet pulls in beside it: `@import`s and `url()`s that name no scheme or root. */
|
|
188
|
+
function stylesheetImports(code: string): string[] {
|
|
189
|
+
const text = code.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
190
|
+
const found: string[] = []
|
|
191
|
+
for (const match of text.matchAll(
|
|
192
|
+
/@import\s+(?:url\(\s*)?["']?([^"'()\s;]+)|url\(\s*["']?([^"'()\s]+)/g,
|
|
193
|
+
)) {
|
|
194
|
+
const reference = match[1] ?? match[2] ?? ""
|
|
195
|
+
if (reference !== "" && !/^(?:[a-z][\w+.-]*:|\/|#|~)/i.test(reference)) found.push(reference)
|
|
196
|
+
}
|
|
197
|
+
return found
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Every string target of an export value, under every condition. */
|
|
201
|
+
function targetsOf(value: unknown): string[] {
|
|
202
|
+
if (typeof value === "string") return value.startsWith("./") ? [value] : []
|
|
203
|
+
if (Array.isArray(value)) return value.flatMap(targetsOf)
|
|
204
|
+
if (typeof value === "object" && value !== null) return Object.values(value).flatMap(targetsOf)
|
|
205
|
+
return []
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** `exports` as subpath entries; without it, the root is `main`/`module`/`browser` and any file a subpath. */
|
|
209
|
+
function exportEntries(
|
|
210
|
+
manifest: Readonly<Record<string, unknown>>,
|
|
211
|
+
entries: Readonly<Record<string, PackageEnvironment>>,
|
|
212
|
+
): Array<readonly [string, readonly string[]]> {
|
|
213
|
+
const exports = manifest.exports
|
|
214
|
+
if (exports === undefined || exports === null) {
|
|
215
|
+
const roots = [manifest.main, manifest.module, manifest.browser]
|
|
216
|
+
.filter((root): root is string => typeof root === "string")
|
|
217
|
+
.map((root) => (root.startsWith("./") ? root : `./${root}`))
|
|
218
|
+
return [
|
|
219
|
+
[".", roots.length > 0 ? roots : ["./index.js"]],
|
|
220
|
+
...Object.keys(entries)
|
|
221
|
+
.filter((key) => key !== ".")
|
|
222
|
+
.map((key) => [key, [key]] as const),
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
if (typeof exports !== "object" || Array.isArray(exports)) return [[".", targetsOf(exports)]]
|
|
226
|
+
const keys = Object.keys(exports)
|
|
227
|
+
if (keys.length === 0 || !keys.every((key) => key.startsWith(".")))
|
|
228
|
+
return [[".", targetsOf(exports)]]
|
|
229
|
+
return Object.entries(exports).map(([key, value]) => [key, targetsOf(value)] as const)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Every file under `dir`, outside `node_modules`. */
|
|
233
|
+
function filesUnder(dir: string): string[] {
|
|
234
|
+
let names: string[]
|
|
235
|
+
try {
|
|
236
|
+
names = readdirSync(dir, { recursive: true, encoding: "utf8" })
|
|
237
|
+
} catch {
|
|
238
|
+
return []
|
|
239
|
+
}
|
|
240
|
+
return names
|
|
241
|
+
.filter((name) => !/(?:^|[\\/])node_modules(?:[\\/]|$)/.test(name))
|
|
242
|
+
.map((name) => join(dir, name))
|
|
243
|
+
.filter(isFile)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Which mapped entries reach each file of the package at `dir` (a real path). */
|
|
247
|
+
export function entryOwnership(
|
|
248
|
+
dir: string,
|
|
249
|
+
manifest: Readonly<Record<string, unknown>>,
|
|
250
|
+
entries: Readonly<Record<string, PackageEnvironment>>,
|
|
251
|
+
): EntryOwnership {
|
|
252
|
+
const owners = new Map<string, Set<PackageEnvironment>>()
|
|
253
|
+
const unmapped = new Set<string>()
|
|
254
|
+
const queue: Array<readonly [string, PackageEnvironment]> = []
|
|
255
|
+
const reach = (path: string, side: PackageEnvironment): void => {
|
|
256
|
+
const file = real(path)
|
|
257
|
+
if (!file.startsWith(`${dir}/`) || file.slice(dir.length).includes("/node_modules/")) return
|
|
258
|
+
const sides = owners.get(file) ?? new Set<PackageEnvironment>()
|
|
259
|
+
if (sides.has(side)) return
|
|
260
|
+
sides.add(side)
|
|
261
|
+
owners.set(file, sides)
|
|
262
|
+
queue.push([file, side])
|
|
263
|
+
}
|
|
264
|
+
const sideOf = (subpath: string, exportKey = subpath): PackageEnvironment | undefined => {
|
|
265
|
+
const key = entryKey(entries, subpath)
|
|
266
|
+
if (key === undefined) unmapped.add(exportKey)
|
|
267
|
+
return key === undefined ? undefined : entries[key]
|
|
268
|
+
}
|
|
269
|
+
for (const [key, targets] of exportEntries(manifest, entries)) {
|
|
270
|
+
const star = key.indexOf("*")
|
|
271
|
+
if (star === -1) {
|
|
272
|
+
const side = sideOf(key)
|
|
273
|
+
if (side === undefined) continue
|
|
274
|
+
for (const target of targets) {
|
|
275
|
+
const file = target.includes("*") ? undefined : probe(join(dir, target))
|
|
276
|
+
if (file !== undefined) reach(file, side)
|
|
277
|
+
}
|
|
278
|
+
continue
|
|
279
|
+
}
|
|
280
|
+
// A pattern entry: each file a target pattern matches is the subpath its `*` spells.
|
|
281
|
+
for (const target of targets) {
|
|
282
|
+
const at = target.indexOf("*")
|
|
283
|
+
if (at === -1) continue
|
|
284
|
+
const prefix = target.slice(0, at)
|
|
285
|
+
const suffix = target.slice(at + 1)
|
|
286
|
+
for (const file of filesUnder(join(dir, prefix.slice(0, prefix.lastIndexOf("/") + 1)))) {
|
|
287
|
+
const path = `./${relative(dir, file).replaceAll("\\", "/")}`
|
|
288
|
+
if (path.length <= prefix.length + suffix.length) continue
|
|
289
|
+
if (!path.startsWith(prefix) || !path.endsWith(suffix)) continue
|
|
290
|
+
const matched = path.slice(prefix.length, path.length - suffix.length)
|
|
291
|
+
const side = sideOf(`${key.slice(0, star)}${matched}${key.slice(star + 1)}`, key)
|
|
292
|
+
if (side !== undefined) reach(file, side)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const imports = new Map<string, readonly string[]>()
|
|
297
|
+
for (const [file, side] of queue) {
|
|
298
|
+
const script = SCRIPT.test(file) && !DECLARATION.test(file)
|
|
299
|
+
if (!script && !STYLESHEET.test(file)) continue
|
|
300
|
+
let specifiers = imports.get(file)
|
|
301
|
+
if (specifiers === undefined) {
|
|
302
|
+
try {
|
|
303
|
+
const code = readFileSync(file, "utf8")
|
|
304
|
+
specifiers = script ? relativeImports(code) : stylesheetImports(code)
|
|
305
|
+
} catch {
|
|
306
|
+
specifiers = []
|
|
307
|
+
}
|
|
308
|
+
imports.set(file, specifiers)
|
|
309
|
+
}
|
|
310
|
+
for (const specifier of specifiers) {
|
|
311
|
+
const found = probe(join(dirname(file), withoutQuery(specifier)))
|
|
312
|
+
if (found !== undefined) reach(found, side)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return { owners, unmapped: [...unmapped].sort() }
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* The `package.json` of the installed package `name`, as Node finds it: the nearest
|
|
320
|
+
* `node_modules/<name>` at or above `fromDir`.
|
|
321
|
+
*/
|
|
322
|
+
export function installedManifest(fromDir: string, name: string): string | undefined {
|
|
323
|
+
let dir = fromDir
|
|
324
|
+
for (;;) {
|
|
325
|
+
const manifest = join(dir, "node_modules", name, "package.json")
|
|
326
|
+
if (isFile(manifest)) return manifest
|
|
327
|
+
const parent = dirname(dir)
|
|
328
|
+
if (parent === dir) return undefined
|
|
329
|
+
dir = parent
|
|
330
|
+
}
|
|
331
|
+
}
|