@endora-commerce/cli 0.100.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/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/bin/endora.d.ts +28 -0
- package/dist/bin/endora.d.ts.map +1 -0
- package/dist/bin/endora.js +926 -0
- package/dist/bin/endora.js.map +1 -0
- package/dist/check/estate.d.ts +189 -0
- package/dist/check/estate.d.ts.map +1 -0
- package/dist/check/estate.js +1037 -0
- package/dist/check/estate.js.map +1 -0
- package/dist/check/hosts.d.ts +25 -0
- package/dist/check/hosts.d.ts.map +1 -0
- package/dist/check/hosts.js +1347 -0
- package/dist/check/hosts.js.map +1 -0
- package/dist/check/index.d.ts +60 -0
- package/dist/check/index.d.ts.map +1 -0
- package/dist/check/index.js +111 -0
- package/dist/check/index.js.map +1 -0
- package/dist/check/layout.d.ts +136 -0
- package/dist/check/layout.d.ts.map +1 -0
- package/dist/check/layout.js +262 -0
- package/dist/check/layout.js.map +1 -0
- package/dist/check/ledger.d.ts +98 -0
- package/dist/check/ledger.d.ts.map +1 -0
- package/dist/check/ledger.js +173 -0
- package/dist/check/ledger.js.map +1 -0
- package/dist/check/peer-owners.d.ts +116 -0
- package/dist/check/peer-owners.d.ts.map +1 -0
- package/dist/check/peer-owners.js +225 -0
- package/dist/check/peer-owners.js.map +1 -0
- package/dist/check/report.d.ts +33 -0
- package/dist/check/report.d.ts.map +1 -0
- package/dist/check/report.js +107 -0
- package/dist/check/report.js.map +1 -0
- package/dist/check/run.d.ts +147 -0
- package/dist/check/run.d.ts.map +1 -0
- package/dist/check/run.js +111 -0
- package/dist/check/run.js.map +1 -0
- package/dist/checks.d.ts +17 -0
- package/dist/checks.d.ts.map +1 -0
- package/dist/checks.js +17 -0
- package/dist/checks.js.map +1 -0
- package/dist/dev/index.d.ts +83 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +298 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/generate/divergence.d.ts +38 -0
- package/dist/generate/divergence.d.ts.map +1 -0
- package/dist/generate/divergence.js +237 -0
- package/dist/generate/divergence.js.map +1 -0
- package/dist/generate/index.d.ts +90 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +369 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs/declaration.d.ts +18 -0
- package/dist/inputs/declaration.d.ts.map +1 -0
- package/dist/inputs/declaration.js +64 -0
- package/dist/inputs/declaration.js.map +1 -0
- package/dist/inputs/env-file.d.ts +73 -0
- package/dist/inputs/env-file.d.ts.map +1 -0
- package/dist/inputs/env-file.js +134 -0
- package/dist/inputs/env-file.js.map +1 -0
- package/dist/inputs/prompt.d.ts +21 -0
- package/dist/inputs/prompt.d.ts.map +1 -0
- package/dist/inputs/prompt.js +59 -0
- package/dist/inputs/prompt.js.map +1 -0
- package/dist/inputs/resolve.d.ts +163 -0
- package/dist/inputs/resolve.d.ts.map +1 -0
- package/dist/inputs/resolve.js +290 -0
- package/dist/inputs/resolve.js.map +1 -0
- package/dist/install/host.d.ts +27 -0
- package/dist/install/host.d.ts.map +1 -0
- package/dist/install/host.js +90 -0
- package/dist/install/host.js.map +1 -0
- package/dist/install/index.d.ts +173 -0
- package/dist/install/index.d.ts.map +1 -0
- package/dist/install/index.js +793 -0
- package/dist/install/index.js.map +1 -0
- package/dist/install/wizard.d.ts +144 -0
- package/dist/install/wizard.d.ts.map +1 -0
- package/dist/install/wizard.js +362 -0
- package/dist/install/wizard.js.map +1 -0
- package/dist/lib/admin-artefacts.d.ts +70 -0
- package/dist/lib/admin-artefacts.d.ts.map +1 -0
- package/dist/lib/admin-artefacts.js +354 -0
- package/dist/lib/admin-artefacts.js.map +1 -0
- package/dist/lib/admin-surfaces.d.ts +298 -0
- package/dist/lib/admin-surfaces.d.ts.map +1 -0
- package/dist/lib/admin-surfaces.js +669 -0
- package/dist/lib/admin-surfaces.js.map +1 -0
- package/dist/lib/delegated-composer.d.ts +85 -0
- package/dist/lib/delegated-composer.d.ts.map +1 -0
- package/dist/lib/delegated-composer.js +241 -0
- package/dist/lib/delegated-composer.js.map +1 -0
- package/dist/lib/divergence-artefacts.d.ts +305 -0
- package/dist/lib/divergence-artefacts.d.ts.map +1 -0
- package/dist/lib/divergence-artefacts.js +828 -0
- package/dist/lib/divergence-artefacts.js.map +1 -0
- package/dist/lib/divergence.d.ts +337 -0
- package/dist/lib/divergence.d.ts.map +1 -0
- package/dist/lib/divergence.js +1005 -0
- package/dist/lib/divergence.js.map +1 -0
- package/dist/lib/docs-artefacts.d.ts +395 -0
- package/dist/lib/docs-artefacts.d.ts.map +1 -0
- package/dist/lib/docs-artefacts.js +781 -0
- package/dist/lib/docs-artefacts.js.map +1 -0
- package/dist/lib/emitted-exports.d.ts +21 -0
- package/dist/lib/emitted-exports.d.ts.map +1 -0
- package/dist/lib/emitted-exports.js +96 -0
- package/dist/lib/emitted-exports.js.map +1 -0
- package/dist/lib/emitted-freshness.d.ts +112 -0
- package/dist/lib/emitted-freshness.d.ts.map +1 -0
- package/dist/lib/emitted-freshness.js +288 -0
- package/dist/lib/emitted-freshness.js.map +1 -0
- package/dist/lib/entity-index-artefact.d.ts +95 -0
- package/dist/lib/entity-index-artefact.d.ts.map +1 -0
- package/dist/lib/entity-index-artefact.js +210 -0
- package/dist/lib/entity-index-artefact.js.map +1 -0
- package/dist/lib/instance-build-inputs.d.ts +108 -0
- package/dist/lib/instance-build-inputs.d.ts.map +1 -0
- package/dist/lib/instance-build-inputs.js +165 -0
- package/dist/lib/instance-build-inputs.js.map +1 -0
- package/dist/lib/module-docs.d.ts +473 -0
- package/dist/lib/module-docs.d.ts.map +1 -0
- package/dist/lib/module-docs.js +711 -0
- package/dist/lib/module-docs.js.map +1 -0
- package/dist/lib/module-package-subpaths.d.ts +56 -0
- package/dist/lib/module-package-subpaths.d.ts.map +1 -0
- package/dist/lib/module-package-subpaths.js +223 -0
- package/dist/lib/module-package-subpaths.js.map +1 -0
- package/dist/lib/module-packages.d.ts +200 -0
- package/dist/lib/module-packages.d.ts.map +1 -0
- package/dist/lib/module-packages.js +580 -0
- package/dist/lib/module-packages.js.map +1 -0
- package/dist/lib/module-population.d.ts +129 -0
- package/dist/lib/module-population.d.ts.map +1 -0
- package/dist/lib/module-population.js +172 -0
- package/dist/lib/module-population.js.map +1 -0
- package/dist/lib/module-roots.d.ts +337 -0
- package/dist/lib/module-roots.d.ts.map +1 -0
- package/dist/lib/module-roots.js +586 -0
- package/dist/lib/module-roots.js.map +1 -0
- package/dist/lib/nested-checkouts.d.ts +33 -0
- package/dist/lib/nested-checkouts.d.ts.map +1 -0
- package/dist/lib/nested-checkouts.js +160 -0
- package/dist/lib/nested-checkouts.js.map +1 -0
- package/dist/lib/platform-root.d.ts +43 -0
- package/dist/lib/platform-root.d.ts.map +1 -0
- package/dist/lib/platform-root.js +134 -0
- package/dist/lib/platform-root.js.map +1 -0
- package/dist/lib/platform-surface.d.ts +235 -0
- package/dist/lib/platform-surface.d.ts.map +1 -0
- package/dist/lib/platform-surface.js +393 -0
- package/dist/lib/platform-surface.js.map +1 -0
- package/dist/lib/port-registrations.d.ts +223 -0
- package/dist/lib/port-registrations.d.ts.map +1 -0
- package/dist/lib/port-registrations.js +532 -0
- package/dist/lib/port-registrations.js.map +1 -0
- package/dist/lib/read-size.d.ts +154 -0
- package/dist/lib/read-size.d.ts.map +1 -0
- package/dist/lib/read-size.js +182 -0
- package/dist/lib/read-size.js.map +1 -0
- package/dist/lib/registration-owners.d.ts +79 -0
- package/dist/lib/registration-owners.d.ts.map +1 -0
- package/dist/lib/registration-owners.js +77 -0
- package/dist/lib/registration-owners.js.map +1 -0
- package/dist/lib/release-index.d.ts +53 -0
- package/dist/lib/release-index.d.ts.map +1 -0
- package/dist/lib/release-index.js +162 -0
- package/dist/lib/release-index.js.map +1 -0
- package/dist/lib/repeating-timers.d.ts +79 -0
- package/dist/lib/repeating-timers.d.ts.map +1 -0
- package/dist/lib/repeating-timers.js +189 -0
- package/dist/lib/repeating-timers.js.map +1 -0
- package/dist/lib/source-text.d.ts +34 -0
- package/dist/lib/source-text.d.ts.map +1 -0
- package/dist/lib/source-text.js +80 -0
- package/dist/lib/source-text.js.map +1 -0
- package/dist/lib/specifiers.d.ts +20 -0
- package/dist/lib/specifiers.d.ts.map +1 -0
- package/dist/lib/specifiers.js +130 -0
- package/dist/lib/specifiers.js.map +1 -0
- package/dist/lib/sql-tables.d.ts +166 -0
- package/dist/lib/sql-tables.d.ts.map +1 -0
- package/dist/lib/sql-tables.js +464 -0
- package/dist/lib/sql-tables.js.map +1 -0
- package/dist/lib/switchable-modules.d.ts +54 -0
- package/dist/lib/switchable-modules.d.ts.map +1 -0
- package/dist/lib/switchable-modules.js +104 -0
- package/dist/lib/switchable-modules.js.map +1 -0
- package/dist/lib/tailwind-sources.d.ts +136 -0
- package/dist/lib/tailwind-sources.d.ts.map +1 -0
- package/dist/lib/tailwind-sources.js +307 -0
- package/dist/lib/tailwind-sources.js.map +1 -0
- package/dist/lib/ui-layer.d.ts +54 -0
- package/dist/lib/ui-layer.d.ts.map +1 -0
- package/dist/lib/ui-layer.js +57 -0
- package/dist/lib/ui-layer.js.map +1 -0
- package/dist/lib/workspace-packages.d.ts +186 -0
- package/dist/lib/workspace-packages.d.ts.map +1 -0
- package/dist/lib/workspace-packages.js +351 -0
- package/dist/lib/workspace-packages.js.map +1 -0
- package/dist/new-instance/deploy.d.ts +211 -0
- package/dist/new-instance/deploy.d.ts.map +1 -0
- package/dist/new-instance/deploy.js +1381 -0
- package/dist/new-instance/deploy.js.map +1 -0
- package/dist/new-instance/docs-toolchain.d.ts +66 -0
- package/dist/new-instance/docs-toolchain.d.ts.map +1 -0
- package/dist/new-instance/docs-toolchain.js +69 -0
- package/dist/new-instance/docs-toolchain.js.map +1 -0
- package/dist/new-instance/host.d.ts +124 -0
- package/dist/new-instance/host.d.ts.map +1 -0
- package/dist/new-instance/host.js +276 -0
- package/dist/new-instance/host.js.map +1 -0
- package/dist/new-instance/index.d.ts +118 -0
- package/dist/new-instance/index.d.ts.map +1 -0
- package/dist/new-instance/index.js +567 -0
- package/dist/new-instance/index.js.map +1 -0
- package/dist/new-instance/modules.d.ts +188 -0
- package/dist/new-instance/modules.d.ts.map +1 -0
- package/dist/new-instance/modules.js +392 -0
- package/dist/new-instance/modules.js.map +1 -0
- package/dist/new-instance/template.d.ts +505 -0
- package/dist/new-instance/template.d.ts.map +1 -0
- package/dist/new-instance/template.js +1886 -0
- package/dist/new-instance/template.js.map +1 -0
- package/dist/new-module/emit.d.ts +67 -0
- package/dist/new-module/emit.d.ts.map +1 -0
- package/dist/new-module/emit.js +1393 -0
- package/dist/new-module/emit.js.map +1 -0
- package/dist/new-module/host.d.ts +67 -0
- package/dist/new-module/host.d.ts.map +1 -0
- package/dist/new-module/host.js +224 -0
- package/dist/new-module/host.js.map +1 -0
- package/dist/new-module/index.d.ts +32 -0
- package/dist/new-module/index.d.ts.map +1 -0
- package/dist/new-module/index.js +193 -0
- package/dist/new-module/index.js.map +1 -0
- package/dist/new-module/spec.d.ts +188 -0
- package/dist/new-module/spec.d.ts.map +1 -0
- package/dist/new-module/spec.js +404 -0
- package/dist/new-module/spec.js.map +1 -0
- package/dist/new-module/text.d.ts +15 -0
- package/dist/new-module/text.d.ts.map +1 -0
- package/dist/new-module/text.js +22 -0
- package/dist/new-module/text.js.map +1 -0
- package/dist/new-storefront/dockerfile.d.ts +20 -0
- package/dist/new-storefront/dockerfile.d.ts.map +1 -0
- package/dist/new-storefront/dockerfile.js +131 -0
- package/dist/new-storefront/dockerfile.js.map +1 -0
- package/dist/new-storefront/gitignore.d.ts +23 -0
- package/dist/new-storefront/gitignore.d.ts.map +1 -0
- package/dist/new-storefront/gitignore.js +39 -0
- package/dist/new-storefront/gitignore.js.map +1 -0
- package/dist/new-storefront/index.d.ts +93 -0
- package/dist/new-storefront/index.d.ts.map +1 -0
- package/dist/new-storefront/index.js +329 -0
- package/dist/new-storefront/index.js.map +1 -0
- package/dist/new-storefront/npmrc.d.ts +98 -0
- package/dist/new-storefront/npmrc.d.ts.map +1 -0
- package/dist/new-storefront/npmrc.js +217 -0
- package/dist/new-storefront/npmrc.js.map +1 -0
- package/dist/new-storefront/reference.d.ts +189 -0
- package/dist/new-storefront/reference.d.ts.map +1 -0
- package/dist/new-storefront/reference.js +430 -0
- package/dist/new-storefront/reference.js.map +1 -0
- package/dist/new-storefront/rewrite.d.ts +171 -0
- package/dist/new-storefront/rewrite.d.ts.map +1 -0
- package/dist/new-storefront/rewrite.js +701 -0
- package/dist/new-storefront/rewrite.js.map +1 -0
- package/dist/release-index.json +284 -0
- package/dist/rules/action-route-permissions.d.ts +141 -0
- package/dist/rules/action-route-permissions.d.ts.map +1 -0
- package/dist/rules/action-route-permissions.js +556 -0
- package/dist/rules/action-route-permissions.js.map +1 -0
- package/dist/rules/bundle-pairing.d.ts +74 -0
- package/dist/rules/bundle-pairing.d.ts.map +1 -0
- package/dist/rules/bundle-pairing.js +281 -0
- package/dist/rules/bundle-pairing.js.map +1 -0
- package/dist/rules/channel-resolution.d.ts +17 -0
- package/dist/rules/channel-resolution.d.ts.map +1 -0
- package/dist/rules/channel-resolution.js +382 -0
- package/dist/rules/channel-resolution.js.map +1 -0
- package/dist/rules/command-coverage.d.ts +210 -0
- package/dist/rules/command-coverage.d.ts.map +1 -0
- package/dist/rules/command-coverage.js +714 -0
- package/dist/rules/command-coverage.js.map +1 -0
- package/dist/rules/container-imports.d.ts +60 -0
- package/dist/rules/container-imports.d.ts.map +1 -0
- package/dist/rules/container-imports.js +158 -0
- package/dist/rules/container-imports.js.map +1 -0
- package/dist/rules/default-language-prose.d.ts +212 -0
- package/dist/rules/default-language-prose.d.ts.map +1 -0
- package/dist/rules/default-language-prose.js +710 -0
- package/dist/rules/default-language-prose.js.map +1 -0
- package/dist/rules/diacritic-folds.d.ts +238 -0
- package/dist/rules/diacritic-folds.d.ts.map +1 -0
- package/dist/rules/diacritic-folds.js +681 -0
- package/dist/rules/diacritic-folds.js.map +1 -0
- package/dist/rules/entity-tenant-classification.d.ts +171 -0
- package/dist/rules/entity-tenant-classification.d.ts.map +1 -0
- package/dist/rules/entity-tenant-classification.js +323 -0
- package/dist/rules/entity-tenant-classification.js.map +1 -0
- package/dist/rules/entry-presence.d.ts +142 -0
- package/dist/rules/entry-presence.d.ts.map +1 -0
- package/dist/rules/entry-presence.js +339 -0
- package/dist/rules/entry-presence.js.map +1 -0
- package/dist/rules/entry-scope.d.ts +91 -0
- package/dist/rules/entry-scope.d.ts.map +1 -0
- package/dist/rules/entry-scope.js +404 -0
- package/dist/rules/entry-scope.js.map +1 -0
- package/dist/rules/env-inputs.d.ts +222 -0
- package/dist/rules/env-inputs.d.ts.map +1 -0
- package/dist/rules/env-inputs.js +951 -0
- package/dist/rules/env-inputs.js.map +1 -0
- package/dist/rules/kernel-boundary.d.ts +37 -0
- package/dist/rules/kernel-boundary.d.ts.map +1 -0
- package/dist/rules/kernel-boundary.js +195 -0
- package/dist/rules/kernel-boundary.js.map +1 -0
- package/dist/rules/nul-bytes.d.ts +233 -0
- package/dist/rules/nul-bytes.d.ts.map +1 -0
- package/dist/rules/nul-bytes.js +332 -0
- package/dist/rules/nul-bytes.js.map +1 -0
- package/dist/rules/platform-surface.d.ts +479 -0
- package/dist/rules/platform-surface.d.ts.map +1 -0
- package/dist/rules/platform-surface.js +749 -0
- package/dist/rules/platform-surface.js.map +1 -0
- package/dist/rules/port-catches.d.ts +225 -0
- package/dist/rules/port-catches.d.ts.map +1 -0
- package/dist/rules/port-catches.js +1374 -0
- package/dist/rules/port-catches.js.map +1 -0
- package/dist/rules/port-shape.d.ts +213 -0
- package/dist/rules/port-shape.d.ts.map +1 -0
- package/dist/rules/port-shape.js +670 -0
- package/dist/rules/port-shape.js.map +1 -0
- package/dist/rules/queue-names.d.ts +108 -0
- package/dist/rules/queue-names.d.ts.map +1 -0
- package/dist/rules/queue-names.js +395 -0
- package/dist/rules/queue-names.js.map +1 -0
- package/dist/rules/singleton-identity.d.ts +205 -0
- package/dist/rules/singleton-identity.d.ts.map +1 -0
- package/dist/rules/singleton-identity.js +830 -0
- package/dist/rules/singleton-identity.js.map +1 -0
- package/dist/rules/subscribe-seam.d.ts +121 -0
- package/dist/rules/subscribe-seam.d.ts.map +1 -0
- package/dist/rules/subscribe-seam.js +594 -0
- package/dist/rules/subscribe-seam.js.map +1 -0
- package/dist/rules/transaction-context.d.ts +40 -0
- package/dist/rules/transaction-context.d.ts.map +1 -0
- package/dist/rules/transaction-context.js +294 -0
- package/dist/rules/transaction-context.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CI check — every non-HTTP entry point establishes a scope (feature 072, T037).
|
|
3
|
+
*
|
|
4
|
+
* The HTTP path has had an ambient `TenantContext` since feature 050 and now
|
|
5
|
+
* gets a resolution scope with it (`kernel/request-scope-hook.ts`). Everything
|
|
6
|
+
* else that starts an execution of its own had no such guarantee: measured
|
|
7
|
+
* before this feature, the 15 CLI scripts mentioned `TenantContext` **zero**
|
|
8
|
+
* times, two of the four interval sweeps established nothing at the timer, and
|
|
9
|
+
* the webhook queue's consumer established nothing at all. They worked because
|
|
10
|
+
* the rows they happen to touch carry no automatic tenant filter — an accident
|
|
11
|
+
* of entity classification, not a property of the code.
|
|
12
|
+
*
|
|
13
|
+
* ## The population is **sites**, not files (issue #237)
|
|
14
|
+
*
|
|
15
|
+
* This check used to classify *files*, and said so: "a file that opens a scope
|
|
16
|
+
* somewhere and forgets it elsewhere is a code-review problem". Code review is
|
|
17
|
+
* what missed it. `kernel/lifecycle/registry-cache.ts` read `module_registrations`
|
|
18
|
+
* and `settings` from a Redis pub/sub handler with no scope at all, and this
|
|
19
|
+
* check reported the file `scoped` off a correctly-wrapped `setInterval` 130
|
|
20
|
+
* lines below (issue #235). The file-level answer is a disjunction — one right
|
|
21
|
+
* entry point vouches for every other one in the same file — and six files in
|
|
22
|
+
* this tree carry more than one, which is precisely where a disjunction can hide
|
|
23
|
+
* something.
|
|
24
|
+
*
|
|
25
|
+
* So an entry point is a **site**, and each site answers for itself. Six classes:
|
|
26
|
+
*
|
|
27
|
+
* - **CLI scripts** — anything under a `scripts/` directory in `src/`;
|
|
28
|
+
* - **Declared programs** — a `src/` file `package.json` runs as a process of
|
|
29
|
+
* its own (see below);
|
|
30
|
+
* - **BullMQ consumers** — each `new Worker(...)` construction;
|
|
31
|
+
* - **Interval sweeps** — each repeating timer. `interval` is the *shape*, not
|
|
32
|
+
* the constructor: `setInterval`, and equally a `setTimeout` whose callback
|
|
33
|
+
* re-arms it. It is also the word the scope itself uses
|
|
34
|
+
* (`ScopeEntryPointKind`), which is why the label stays;
|
|
35
|
+
* - **Pub/sub handlers** — each `x.on('message', …)`. A message delivered off a
|
|
36
|
+
* socket the composition opened has no caller to inherit a context from;
|
|
37
|
+
* this is the class issue #235 was in, and the class this check had no
|
|
38
|
+
* population for at all;
|
|
39
|
+
* - **Process-lifecycle handlers** — each `process.on/once(...)`. Same
|
|
40
|
+
* argument, and `kernel/container.ts`'s `installShutdownDisposal` is the
|
|
41
|
+
* site that proves the file-level population could not reach it:
|
|
42
|
+
* `container.ts` is under no `scripts/` directory, is no declared program,
|
|
43
|
+
* constructs no `Worker` and starts no timer, so *no* file-level class ever
|
|
44
|
+
* contained it.
|
|
45
|
+
*
|
|
46
|
+
* The first two are file-level by nature — the entry is the file's own top-level
|
|
47
|
+
* execution — and they keep one site per file. Their scope question is asked over
|
|
48
|
+
* the file **minus** the callbacks of the site-shaped entry points in it, so a
|
|
49
|
+
* program cannot read as scoped off a scope its Worker opens. That subtraction is
|
|
50
|
+
* the file-level disjunction, removed at its last hiding place.
|
|
51
|
+
*
|
|
52
|
+
* Boot reconcilers are a seventh class and are *not* detectable: "a function the
|
|
53
|
+
* composition root awaits before serving" has no syntactic marker. They are
|
|
54
|
+
* covered by review and by `composition.ts` calling `enterSystemScope` for each
|
|
55
|
+
* of the four.
|
|
56
|
+
*
|
|
57
|
+
* ## What "this site opens a scope" means, and how far it looks
|
|
58
|
+
*
|
|
59
|
+
* A site is scoped when `enterSystemScope` / `enterPlatformScope` is called in
|
|
60
|
+
* its own callback, or in a function bound **in the same file** that the callback
|
|
61
|
+
* calls — **one hop**, the depth `check-port-catches` follows `this.<method>()`
|
|
62
|
+
* to. Deeper needs a call graph, which is a different project.
|
|
63
|
+
*
|
|
64
|
+
* Binding an identifier callback is **not** one of those hops: in
|
|
65
|
+
* `new Worker(QUEUE, processor, …)`, `processor` *is* the callback, and half the
|
|
66
|
+
* queues in this tree are written that way. The hop is counted from the callback
|
|
67
|
+
* body. So what this cannot see, stated rather than discovered later:
|
|
68
|
+
*
|
|
69
|
+
* - a callback that delegates to an **imported** function which opens the
|
|
70
|
+
* scope — reported as unscoped, and the ledger is where that gets answered;
|
|
71
|
+
* - a callback that delegates to a **method** (`this.handleMessage(…)`): only
|
|
72
|
+
* module-level bindings are resolved;
|
|
73
|
+
* - a scope opened two hops below the callback body.
|
|
74
|
+
*
|
|
75
|
+
* All three fail *loudly* — a site reads unscoped — which is the direction a
|
|
76
|
+
* blind spot has to fail in.
|
|
77
|
+
*
|
|
78
|
+
* ## Why `package.json` is the second source of the population (issue #228)
|
|
79
|
+
*
|
|
80
|
+
* The shape classes were written from what the tree held when FR-020 landed.
|
|
81
|
+
* `src/seeds/dev-catalog-seed.ts` is none of them: it is a top-level `main()`
|
|
82
|
+
* that truncates and repopulates a dozen modules' tables, run by
|
|
83
|
+
* `pnpm --filter backend run seed:dev`, and it established no scope. The check
|
|
84
|
+
* printed `unscoped=0` — and that zero said nothing about the file, because the
|
|
85
|
+
* file was never in the population.
|
|
86
|
+
*
|
|
87
|
+
* That is issue #215's failure by another mechanism: there the *walks* came back
|
|
88
|
+
* short, here the *population definition* excluded a real entry point. Both
|
|
89
|
+
* report a green that means "not looking", and nothing in the output told the
|
|
90
|
+
* two apart.
|
|
91
|
+
*
|
|
92
|
+
* So the population has a second source, and it is not another shape: it is the
|
|
93
|
+
* repository's own declaration of what it runs. Every `src/**.ts` path named by
|
|
94
|
+
* a script in `backend/package.json` is a process entry point by construction —
|
|
95
|
+
* `pnpm run <name>` starts it, no HTTP request is involved, and nothing above it
|
|
96
|
+
* can open a scope on its behalf.
|
|
97
|
+
*
|
|
98
|
+
* The two sources are a **union**, and the seed is the standing proof that the
|
|
99
|
+
* declaration half is load-bearing: it is under no `scripts/` directory and no
|
|
100
|
+
* shape class contains it, so without the `package.json` source it is not in
|
|
101
|
+
* the population at all.
|
|
102
|
+
*
|
|
103
|
+
* The other half used to be cited to `backfill-quote-channel.ts`, a `scripts/`
|
|
104
|
+
* file run directly with no package script of its own — and it was the *only*
|
|
105
|
+
* one, so D-167 deleting it took the citation with it. Today every `scripts/`
|
|
106
|
+
* file is also a declared program, which means the `scripts/` half adds no site
|
|
107
|
+
* this run would otherwise miss. It stays, and the reason is the shape of the
|
|
108
|
+
* two sources rather than today's count: a `scripts/` file is a process entry
|
|
109
|
+
* point because of what it *is*, while a `package.json` entry says only what
|
|
110
|
+
* this repository currently chooses to run. An author who adds a maintenance
|
|
111
|
+
* script and invokes it with `tsx` — which is exactly how the deleted file was
|
|
112
|
+
* run — is back in the case the union exists for, and the check would report
|
|
113
|
+
* `unscoped=0` about a file it never opened. Dropping the shape half would make
|
|
114
|
+
* that silence possible again to save nothing.
|
|
115
|
+
*
|
|
116
|
+
* ## One analysis, two hosts
|
|
117
|
+
*
|
|
118
|
+
* This file is the analysis (`specs/101-endora-check/contracts/package-scope-layout.md`
|
|
119
|
+
* §6). `backend/scripts/check-entry-scope.ts` hosts it over this repository's
|
|
120
|
+
* module walk roots and holds `NO_SCOPE_NEEDED`, which is a ledger of *this*
|
|
121
|
+
* tree's sites; `endora check` hosts it over one module package, where the
|
|
122
|
+
* ledger is the package's own and is applied by `check/ledger.ts` over every
|
|
123
|
+
* rule at once. So {@link violationsOf} and {@link staleAllowances} take the
|
|
124
|
+
* ledger as an argument rather than reading one: a ledger read from inside the
|
|
125
|
+
* analysis is a ledger only one host can have.
|
|
126
|
+
*/
|
|
127
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
128
|
+
import { join } from 'node:path';
|
|
129
|
+
import ts from 'typescript';
|
|
130
|
+
import { callbackOf, calleeName, enclosingName, findRepeatingTimerSites, localFunctions, MODULE_SCOPE, parseScript, receiverName, stringLiteralOf, } from '../lib/repeating-timers.js';
|
|
131
|
+
/** The two functions that open a scope. Nothing else counts as establishing one. */
|
|
132
|
+
const SCOPE_ENTRY_FUNCTIONS = new Set([
|
|
133
|
+
'enterPlatformScope',
|
|
134
|
+
'enterSystemScope',
|
|
135
|
+
]);
|
|
136
|
+
/** Process-lifecycle events: a handler for one of these has no caller either. */
|
|
137
|
+
const PROCESS_EVENTS = new Set([
|
|
138
|
+
'SIGINT',
|
|
139
|
+
'SIGTERM',
|
|
140
|
+
'SIGHUP',
|
|
141
|
+
'SIGQUIT',
|
|
142
|
+
'SIGUSR1',
|
|
143
|
+
'SIGUSR2',
|
|
144
|
+
'beforeExit',
|
|
145
|
+
'exit',
|
|
146
|
+
'uncaughtException',
|
|
147
|
+
'unhandledRejection',
|
|
148
|
+
]);
|
|
149
|
+
/** The scheduler slot of a file-level site: the file's own top-level execution. */
|
|
150
|
+
export const FILE_SCOPE = '<file>';
|
|
151
|
+
/**
|
|
152
|
+
* `<file>:<scheduler>:<construct>` — the ledger key, and the identity of a site.
|
|
153
|
+
*
|
|
154
|
+
* Line-independent, in the idiom of `check-entry-presence.ts`'s `keyOf`: moving
|
|
155
|
+
* code inside a file does not invalidate an entry, and re-opening the hole
|
|
156
|
+
* somewhere else does not silently inherit one.
|
|
157
|
+
*
|
|
158
|
+
* A key may cover **more than one site**: `index.ts` registers `SIGINT` and
|
|
159
|
+
* `SIGTERM` in the same function with the same construct, and one entry
|
|
160
|
+
* answering for both is what a reader wants there. It is deliberate, and it is
|
|
161
|
+
* the granularity's floor — two sites the key cannot tell apart are two sites
|
|
162
|
+
* one reason has to be true of.
|
|
163
|
+
*/
|
|
164
|
+
export function keyOf(site) {
|
|
165
|
+
return `${site.file}:${site.scheduler}:${site.construct}`;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Every TypeScript source under `dir` — colocated tests included, which is the
|
|
169
|
+
* one difference from the other walks in this estate and is deliberate: a test
|
|
170
|
+
* that starts a worker is an entry point too.
|
|
171
|
+
*
|
|
172
|
+
* Exported because the population is part of the rule, not part of a host.
|
|
173
|
+
*/
|
|
174
|
+
export function collectEntryScopeSources(dir, out = []) {
|
|
175
|
+
for (const name of readdirSync(dir)) {
|
|
176
|
+
const full = join(dir, name);
|
|
177
|
+
if (statSync(full).isDirectory()) {
|
|
178
|
+
if (name === 'node_modules' || name === 'dist')
|
|
179
|
+
continue;
|
|
180
|
+
collectEntryScopeSources(full, out);
|
|
181
|
+
}
|
|
182
|
+
else if (name.endsWith('.ts') && !name.endsWith('.test.ts')) {
|
|
183
|
+
out.push(full);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
/** Every spelling a site-shaped entry point can start with. Loose on purpose — see below. */
|
|
189
|
+
const SITE_TOKENS = /new Worker|setInterval|setTimeout|\.\s*(?:on|once)\s*\(/;
|
|
190
|
+
/**
|
|
191
|
+
* Could this source hold a site-shaped entry point at all?
|
|
192
|
+
*
|
|
193
|
+
* Parsing all 1458 files under `src/` to answer "no" for most of them costs more
|
|
194
|
+
* than the whole check; 54 of them contain one of these tokens anywhere, comments
|
|
195
|
+
* included, and those are the ones that reach the parser.
|
|
196
|
+
*
|
|
197
|
+
* Deliberately **over**-inclusive, and only over-inclusive: this is a raw-text
|
|
198
|
+
* test, so a comment quoting `new Worker(...)` costs one parse and nothing else —
|
|
199
|
+
* the syntax tree still decides. A second, stripped pass would save four of those
|
|
200
|
+
* 54 parses and pay for it with the one failure mode this check exists to remove:
|
|
201
|
+
* a regex-based stripper mangling a line and silently taking a real site out of
|
|
202
|
+
* the population.
|
|
203
|
+
*/
|
|
204
|
+
function mayHoldSite(source) {
|
|
205
|
+
return SITE_TOKENS.test(source);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* The `src/` files `package.json` runs as a process of their own.
|
|
209
|
+
*
|
|
210
|
+
* Read out of the **command**, not out of the script name: `seed:dev` is
|
|
211
|
+
* `pnpm run migration:up && tsx --env-file-if-exists=.env src/seeds/…`, so the
|
|
212
|
+
* entry point is the second of two commands behind three flags. `dist/` paths
|
|
213
|
+
* are ignored (this check reads sources) and so are `scripts/` paths outside
|
|
214
|
+
* `src/`, which the walk never sees.
|
|
215
|
+
*/
|
|
216
|
+
export function declaredProgramEntryPoints(packageJson) {
|
|
217
|
+
const parsed = JSON.parse(packageJson);
|
|
218
|
+
const found = new Set();
|
|
219
|
+
for (const command of Object.values(parsed.scripts ?? {})) {
|
|
220
|
+
for (const match of command.matchAll(/\bsrc\/[\w./@-]+\.ts\b/g))
|
|
221
|
+
found.add(match[0]);
|
|
222
|
+
}
|
|
223
|
+
return [...found].sort();
|
|
224
|
+
}
|
|
225
|
+
const NOTHING_DECLARED = new Set();
|
|
226
|
+
/**
|
|
227
|
+
* The path as the ledger spells it: everything from the last `/src/` on.
|
|
228
|
+
* Derived from the path itself rather than from `SRC_ROOT` so the predicates
|
|
229
|
+
* here are testable without knowing where the checkout lives.
|
|
230
|
+
*
|
|
231
|
+
* **It is the default and no longer the only answer** (feature 080, T040a). A
|
|
232
|
+
* module that has become a workspace package lives at
|
|
233
|
+
* `packages/modules/<id>/src/…`, where "everything from the last `/src/` on"
|
|
234
|
+
* drops the module and leaves `src/services/x.ts` — a key two packages would
|
|
235
|
+
* share. The CLI therefore passes `resolveModuleLayout().displayOf`, which
|
|
236
|
+
* keeps the application's own spelling byte-for-byte and answers repo-relative
|
|
237
|
+
* for anything outside it. The default stays for the predicates' own tests,
|
|
238
|
+
* which have no checkout to resolve.
|
|
239
|
+
*/
|
|
240
|
+
export function relative(file) {
|
|
241
|
+
const marker = file.lastIndexOf('/src/');
|
|
242
|
+
return marker === -1 ? file : file.slice(marker + 1);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Which file-level class this file belongs to, or `null` for neither.
|
|
246
|
+
*
|
|
247
|
+
* A file under `scripts/` that is *also* declared stays `cli`: fourteen of the
|
|
248
|
+
* fifteen are both, and moving them would make the count move for no reason.
|
|
249
|
+
*/
|
|
250
|
+
export function fileLevelKind(file, declared = NOTHING_DECLARED, pathOf = relative) {
|
|
251
|
+
if (/\/scripts\//.test(file))
|
|
252
|
+
return 'cli';
|
|
253
|
+
if (declared.has(pathOf(file)))
|
|
254
|
+
return 'program';
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Does `root` open a scope — directly, or one local hop down?
|
|
259
|
+
*
|
|
260
|
+
* The hop resolves a called identifier against the file's own function bindings,
|
|
261
|
+
* which is how a `new Worker(QUEUE, processor)` whose `processor` wraps itself is
|
|
262
|
+
* read correctly. It stops there on purpose; see the header for what that cannot
|
|
263
|
+
* see, and why every one of those cases fails loudly rather than quietly.
|
|
264
|
+
*/
|
|
265
|
+
function opensScope(root, bindings, search) {
|
|
266
|
+
let found = false;
|
|
267
|
+
const visit = (node) => {
|
|
268
|
+
if (found || search.skip.has(node))
|
|
269
|
+
return;
|
|
270
|
+
if (ts.isCallExpression(node)) {
|
|
271
|
+
const name = calleeName(node);
|
|
272
|
+
if (name !== null) {
|
|
273
|
+
if (SCOPE_ENTRY_FUNCTIONS.has(name)) {
|
|
274
|
+
found = true;
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (search.depth > 0 && ts.isIdentifier(node.expression)) {
|
|
278
|
+
const target = bindings.get(name);
|
|
279
|
+
if (target !== undefined && opensScope(target, bindings, { ...search, depth: 0 })) {
|
|
280
|
+
found = true;
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
node.forEachChild(visit);
|
|
287
|
+
};
|
|
288
|
+
visit(root);
|
|
289
|
+
return found;
|
|
290
|
+
}
|
|
291
|
+
/** Every `new Worker(...)`, pub/sub handler and process-lifecycle handler in a file. */
|
|
292
|
+
function findConstructedSites(sf, bindings) {
|
|
293
|
+
const sites = [];
|
|
294
|
+
const at = (node) => ({
|
|
295
|
+
line: sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1,
|
|
296
|
+
scheduler: enclosingName(node) ?? MODULE_SCOPE,
|
|
297
|
+
});
|
|
298
|
+
const visit = (node) => {
|
|
299
|
+
if (ts.isNewExpression(node) &&
|
|
300
|
+
ts.isIdentifier(node.expression) &&
|
|
301
|
+
node.expression.text === 'Worker') {
|
|
302
|
+
sites.push({
|
|
303
|
+
kind: 'worker',
|
|
304
|
+
construct: 'new Worker',
|
|
305
|
+
node,
|
|
306
|
+
// BullMQ's processor is the second argument; the first is the queue name.
|
|
307
|
+
callback: callbackOf(node.arguments?.[1], bindings),
|
|
308
|
+
...at(node),
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
if (ts.isCallExpression(node)) {
|
|
312
|
+
const name = calleeName(node);
|
|
313
|
+
const event = node.arguments[0] === undefined ? null : stringLiteralOf(node.arguments[0]);
|
|
314
|
+
if (name === 'on' && event === 'message') {
|
|
315
|
+
sites.push({
|
|
316
|
+
kind: 'message',
|
|
317
|
+
construct: "on('message')",
|
|
318
|
+
node,
|
|
319
|
+
callback: callbackOf(node.arguments[1], bindings),
|
|
320
|
+
...at(node),
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else if ((name === 'on' || name === 'once') &&
|
|
324
|
+
receiverName(node) === 'process' &&
|
|
325
|
+
// An event this cannot read as a literal is *in* — `container.ts` loops
|
|
326
|
+
// over its signals, and a population that required a literal would have
|
|
327
|
+
// no site for the one file that motivated the class.
|
|
328
|
+
(event === null || PROCESS_EVENTS.has(event))) {
|
|
329
|
+
sites.push({
|
|
330
|
+
kind: 'process',
|
|
331
|
+
construct: name === 'on' ? 'process.on' : 'process.once',
|
|
332
|
+
node,
|
|
333
|
+
callback: callbackOf(node.arguments[1], bindings),
|
|
334
|
+
...at(node),
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
node.forEachChild(visit);
|
|
339
|
+
};
|
|
340
|
+
sf.forEachChild(visit);
|
|
341
|
+
return sites;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Every entry site in one file, with its own scope answer.
|
|
345
|
+
*
|
|
346
|
+
* The top of the analysis: source **text** in, sites out. A caller — a test
|
|
347
|
+
* especially — decides what the repository says it runs by passing `declared`,
|
|
348
|
+
* the set `declaredProgramEntryPoints` returned.
|
|
349
|
+
*/
|
|
350
|
+
export function findEntrySites(file, source, declared = NOTHING_DECLARED, pathOf = relative) {
|
|
351
|
+
const fileKind = fileLevelKind(file, declared, pathOf);
|
|
352
|
+
if (fileKind === null && !mayHoldSite(source))
|
|
353
|
+
return [];
|
|
354
|
+
const path = pathOf(file);
|
|
355
|
+
const sf = parseScript(file, source);
|
|
356
|
+
const bindings = localFunctions(sf);
|
|
357
|
+
const raw = [
|
|
358
|
+
...findRepeatingTimerSites(sf).map((timer) => ({
|
|
359
|
+
kind: 'interval',
|
|
360
|
+
construct: timer.construct,
|
|
361
|
+
node: timer.call,
|
|
362
|
+
callback: timer.callback,
|
|
363
|
+
line: timer.line,
|
|
364
|
+
scheduler: timer.scheduler,
|
|
365
|
+
})),
|
|
366
|
+
...findConstructedSites(sf, bindings),
|
|
367
|
+
];
|
|
368
|
+
const sites = raw.map((site) => ({
|
|
369
|
+
file: path,
|
|
370
|
+
kind: site.kind,
|
|
371
|
+
construct: site.construct,
|
|
372
|
+
scheduler: site.scheduler,
|
|
373
|
+
line: site.line,
|
|
374
|
+
// A callback this cannot bind to a function in this file is not vouched for.
|
|
375
|
+
scoped: site.callback !== null &&
|
|
376
|
+
opensScope(site.callback, bindings, { depth: 1, skip: new Set() }),
|
|
377
|
+
}));
|
|
378
|
+
if (fileKind !== null) {
|
|
379
|
+
// The file's own top-level execution, asked over everything **except** the
|
|
380
|
+
// bodies that belong to the sites above: a program that reads as scoped off
|
|
381
|
+
// the `enterSystemScope` inside its Worker is the file-level disjunction
|
|
382
|
+
// this check was rewritten to remove.
|
|
383
|
+
const skip = new Set(raw.map((site) => site.callback).filter((cb) => cb !== null));
|
|
384
|
+
sites.unshift({
|
|
385
|
+
file: path,
|
|
386
|
+
kind: fileKind,
|
|
387
|
+
construct: fileKind,
|
|
388
|
+
scheduler: FILE_SCOPE,
|
|
389
|
+
line: 1,
|
|
390
|
+
scoped: opensScope(sf, bindings, { depth: 0, skip }),
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
sites.sort((a, b) => a.line - b.line);
|
|
394
|
+
return sites;
|
|
395
|
+
}
|
|
396
|
+
export function violationsOf(sites, allowed) {
|
|
397
|
+
return sites.filter((site) => !site.scoped && allowed[keyOf(site)] === undefined);
|
|
398
|
+
}
|
|
399
|
+
/** Ledger entries that no longer name an unscoped entry site. */
|
|
400
|
+
export function staleAllowances(sites, allowed) {
|
|
401
|
+
const unscoped = new Set(sites.filter((site) => !site.scoped).map(keyOf));
|
|
402
|
+
return Object.keys(allowed).filter((key) => !unscoped.has(key));
|
|
403
|
+
}
|
|
404
|
+
//# sourceMappingURL=entry-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-scope.js","sourceRoot":"","sources":["../../src/rules/entry-scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { type EnvironmentConsumer, type EnvironmentInput, type EnvironmentInputOwner } from '@endora-commerce/contracts';
|
|
3
|
+
/** The log prefix both hosts print under — one grammar, one spelling. */
|
|
4
|
+
export declare const PREFIX = "[env-inputs]";
|
|
5
|
+
export type EnvInputFindingKind = 'undeclared-input' | 'undeclared-module-input' | 'unread-input' | 'foreign-input' | 'module-declares-a-platform-input' | 'unresolvable-input-name' | 'generable-without-secret' | 'requirement-without-a-consequence' | 'module-input-without-a-settings-verdict' | 'stale-settings-verdict';
|
|
6
|
+
/** What to do about each kind, printed above the findings of that kind. */
|
|
7
|
+
export declare const REMEDIES: Readonly<Record<EnvInputFindingKind, string>>;
|
|
8
|
+
/** One `process.env` / `import.meta.env` member access the walk saw. */
|
|
9
|
+
export interface EnvironmentRead {
|
|
10
|
+
/** The variable, or `null` where the name could not be resolved to a literal. */
|
|
11
|
+
readonly name: string | null;
|
|
12
|
+
/** Repository-relative, POSIX separators. */
|
|
13
|
+
readonly file: string;
|
|
14
|
+
readonly line: number;
|
|
15
|
+
/** Which tree the file belongs to. */
|
|
16
|
+
readonly consumer: EnvironmentConsumer;
|
|
17
|
+
/** How the name was written, for the message. */
|
|
18
|
+
readonly shape: 'literal' | 'const' | 'imported-const' | 'computed';
|
|
19
|
+
/**
|
|
20
|
+
* The module whose sources the file is, or `undefined` for an application's
|
|
21
|
+
* own file.
|
|
22
|
+
*
|
|
23
|
+
* It is what makes the resolution rule — *the platform's declaration, the
|
|
24
|
+
* application's, and the reading module's own, never another module's* —
|
|
25
|
+
* expressible at all (`specs/117-instance-bring-up/` T3-B). Without it a read
|
|
26
|
+
* is only ever a `(name, consumer)` pair, and one module's declaration
|
|
27
|
+
* silently covers every other module's read of the same name: a client
|
|
28
|
+
* installing the reader and not the declarer would then be short a variable
|
|
29
|
+
* this check had reported green.
|
|
30
|
+
*/
|
|
31
|
+
readonly module?: string | undefined;
|
|
32
|
+
}
|
|
33
|
+
/** One author's declaration, as the host loaded it. */
|
|
34
|
+
export interface DeclarationSource {
|
|
35
|
+
/** The author shipping it — what `owner` is reconciled against. */
|
|
36
|
+
readonly author: EnvironmentInputOwner;
|
|
37
|
+
/** Repository-relative path, for the message. */
|
|
38
|
+
readonly file: string;
|
|
39
|
+
readonly inputs: readonly EnvironmentInput[];
|
|
40
|
+
}
|
|
41
|
+
export interface EnvInputFinding {
|
|
42
|
+
readonly kind: EnvInputFindingKind;
|
|
43
|
+
/** The variable, or the declaration that has no name to give. */
|
|
44
|
+
readonly name: string;
|
|
45
|
+
/** Where it was found — a source file for a read, a declaration otherwise. */
|
|
46
|
+
readonly where: string;
|
|
47
|
+
readonly detail: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* What a module's environment input is, once somebody has judged it
|
|
51
|
+
* (`contracts/environment-inputs.md` §4.2).
|
|
52
|
+
*
|
|
53
|
+
* `bootstrap` is a value the platform needs **before the settings store can be
|
|
54
|
+
* read**; `configuration` is a knob that belongs to the Settings module and is
|
|
55
|
+
* wearing an environment variable. The second is not an exemption — it is debt
|
|
56
|
+
* with an owner, and the ledger exists to make the population drainable rather
|
|
57
|
+
* than to bless it (§4.3, §4.4).
|
|
58
|
+
*/
|
|
59
|
+
export interface ModuleEnvironmentVerdict {
|
|
60
|
+
readonly classification: 'bootstrap' | 'configuration';
|
|
61
|
+
/** Why it is not a Setting. One question, answered in a sentence. */
|
|
62
|
+
readonly reason: string;
|
|
63
|
+
}
|
|
64
|
+
/** One module's shard of the Settings-debt ledger, as the host loaded it. */
|
|
65
|
+
export interface ModuleVerdictShard {
|
|
66
|
+
readonly moduleId: string;
|
|
67
|
+
/** Keyed by the variable's name. */
|
|
68
|
+
readonly entries: Readonly<Record<string, ModuleEnvironmentVerdict>>;
|
|
69
|
+
}
|
|
70
|
+
export interface EnvInputsInput {
|
|
71
|
+
readonly declarations: readonly DeclarationSource[];
|
|
72
|
+
readonly reads: readonly EnvironmentRead[];
|
|
73
|
+
/**
|
|
74
|
+
* The Settings-debt ledger, or `undefined` where the caller is not asking.
|
|
75
|
+
*
|
|
76
|
+
* The two states are deliberately distinct. `[]` is *"the ledger was read and
|
|
77
|
+
* holds nothing"*, under which every module-owned declaration lacks a verdict;
|
|
78
|
+
* `undefined` is *"this caller is not reconciling the ledger"*, which is what
|
|
79
|
+
* a red proof about some other finding wants. Collapsing them would make a
|
|
80
|
+
* fixture that says nothing about the ledger report on it anyway.
|
|
81
|
+
*
|
|
82
|
+
* The host always passes it, and refuses a ledger directory that is not there
|
|
83
|
+
* rather than passing `undefined` — a missing ledger must never be the quiet
|
|
84
|
+
* path.
|
|
85
|
+
*/
|
|
86
|
+
readonly settingsVerdicts?: readonly ModuleVerdictShard[] | undefined;
|
|
87
|
+
}
|
|
88
|
+
export interface EnvInputsResult {
|
|
89
|
+
readonly findings: readonly EnvInputFinding[];
|
|
90
|
+
/** Every declared input, across authors. */
|
|
91
|
+
readonly declared: number;
|
|
92
|
+
/** Consumers that contributed both a declaration and at least one read site. */
|
|
93
|
+
readonly consumersCovered: readonly EnvironmentConsumer[];
|
|
94
|
+
/** Inputs declared by a module author, of {@link EnvInputsResult.declared}. */
|
|
95
|
+
readonly declaredByModules: number;
|
|
96
|
+
/** Module ids that declare at least one input. */
|
|
97
|
+
readonly modulesDeclaring: readonly string[];
|
|
98
|
+
}
|
|
99
|
+
/** The whole rule, pure over the record, so a proof enters where a run does. */
|
|
100
|
+
export declare function checkEnvironmentInputs(input: EnvInputsInput): EnvInputsResult;
|
|
101
|
+
/** A file the walk opened, with the tree it belongs to. */
|
|
102
|
+
export interface EnvSourceFile {
|
|
103
|
+
/** Repository-relative, POSIX separators. */
|
|
104
|
+
readonly path: string;
|
|
105
|
+
readonly text: string;
|
|
106
|
+
readonly consumer: EnvironmentConsumer;
|
|
107
|
+
/** The module this file belongs to, where the host could attribute it. */
|
|
108
|
+
readonly module?: string | undefined;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The prefix Vite requires on a variable it takes from the environment.
|
|
112
|
+
*
|
|
113
|
+
* Vite's own `envPrefix`, at its default. A name without it is one of Vite's
|
|
114
|
+
* build-mode constants and is not an operator input — see the header.
|
|
115
|
+
*/
|
|
116
|
+
export declare const VITE_ENVIRONMENT_PREFIX = "VITE_";
|
|
117
|
+
/**
|
|
118
|
+
* Every string constant a file exports or declares at module scope.
|
|
119
|
+
*
|
|
120
|
+
* Only a bare `const X = '…'`, deliberately. A `let`, a computed initialiser
|
|
121
|
+
* and a member of an object literal are all outside it: each is a value that
|
|
122
|
+
* can differ from what the reader sees, and the whole point of resolving a
|
|
123
|
+
* constant here is that its value is decidable from the text.
|
|
124
|
+
*/
|
|
125
|
+
export declare function stringConstants(source: ts.SourceFile): ReadonlyMap<string, string>;
|
|
126
|
+
/**
|
|
127
|
+
* Resolve a relative import specifier against the importing file's directory,
|
|
128
|
+
* in the walk's own key space.
|
|
129
|
+
*
|
|
130
|
+
* POSIX-only and extension-tolerant: the tree writes `./env.mjs` from a `.ts`
|
|
131
|
+
* file (ESM's own rule) and `./env.js` where the target is `env.ts`. A bare
|
|
132
|
+
* specifier resolves to nothing here, which is right — a constant published by
|
|
133
|
+
* a package is not text this walk read.
|
|
134
|
+
*/
|
|
135
|
+
export declare function resolveRelative(fromFile: string, specifier: string): string | null;
|
|
136
|
+
/**
|
|
137
|
+
* Every environment read in the walk, with its name resolved where it can be.
|
|
138
|
+
*
|
|
139
|
+
* The file text is the entry point (issue #130), so a red proof drives exactly
|
|
140
|
+
* what a real run drives.
|
|
141
|
+
*/
|
|
142
|
+
export declare function collectEnvironmentReads(files: readonly EnvSourceFile[]): readonly EnvironmentRead[];
|
|
143
|
+
/** Raised when a declaration file cannot be read as one; a caller turns it into exit 2. */
|
|
144
|
+
export declare class DeclarationUnreadableError extends Error {
|
|
145
|
+
readonly name = "DeclarationUnreadableError";
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* A declaration read out of its own **source text**, never out of a build.
|
|
149
|
+
*
|
|
150
|
+
* ## Why not `import()` the emitted module
|
|
151
|
+
*
|
|
152
|
+
* A module package resolves through its `exports` map at its build output
|
|
153
|
+
* (D-164), so a check that imported one would answer about the previous build —
|
|
154
|
+
* the `stale-artefact` class `check:action-route-permissions` had to grow a
|
|
155
|
+
* refusal for, measured three times as a **false green** on that check. Reading
|
|
156
|
+
* the text removes the question rather than guarding it: the bytes this run
|
|
157
|
+
* judged are the bytes on disk, and the check needs no build to run at all.
|
|
158
|
+
* The `exports` subpath is still the path the *runtime* readers take, and
|
|
159
|
+
* `test/unit/packages/platform-env-subpath.test.ts` is what holds it open.
|
|
160
|
+
*
|
|
161
|
+
* ## What it evaluates, and what it refuses
|
|
162
|
+
*
|
|
163
|
+
* A declaration is data: an array of object literals over strings, booleans,
|
|
164
|
+
* arrays and nested objects. Nothing else is accepted — no identifier, no
|
|
165
|
+
* spread, no call, no concatenation — and an expression outside that grammar is
|
|
166
|
+
* a refusal rather than a value guessed at, because a declaration this analysis
|
|
167
|
+
* cannot read in full is one it must not report on (issue #113).
|
|
168
|
+
*
|
|
169
|
+
* A string is taken literally, so `'\n'` and a template literal with no
|
|
170
|
+
* substitution both arrive as the text they denote. `as const` is unwrapped:
|
|
171
|
+
* it changes a type and no value.
|
|
172
|
+
*/
|
|
173
|
+
export declare function evaluateDeclarationArray(text: string, fileName: string, exportName: string): readonly unknown[];
|
|
174
|
+
/**
|
|
175
|
+
* A module's `env` declaration, read out of its `manifest.ts` **source text**.
|
|
176
|
+
*
|
|
177
|
+
* ## Why text and not the built manifest
|
|
178
|
+
*
|
|
179
|
+
* The same reason {@link evaluateDeclarationArray} gives, with more force: a
|
|
180
|
+
* module package resolves through its own `exports` map at its build output
|
|
181
|
+
* (D-164), so a reader that imported one would answer about the previous build.
|
|
182
|
+
* That is the `stale-artefact` class `check:action-route-permissions` had to
|
|
183
|
+
* grow a refusal for after three measured false greens — an `env` entry edited
|
|
184
|
+
* and not rebuilt would be judged as though it were not there, which for *this*
|
|
185
|
+
* check is a false green in the direction that matters: a declaration the author
|
|
186
|
+
* just wrote, reported as missing, or one they just deleted, reported as
|
|
187
|
+
* present. Reading the text removes the question instead of guarding it, and the
|
|
188
|
+
* run needs no build at all.
|
|
189
|
+
*
|
|
190
|
+
* ## What it reads, and what it refuses
|
|
191
|
+
*
|
|
192
|
+
* Only the `env` property of the object literal handed to `defineModuleManifest`,
|
|
193
|
+
* and only as data. Everything else in the file is ignored, which is not a
|
|
194
|
+
* convenience: `cms`' manifest reads `process.env['CMS_PB_BREAKPOINT_TABLET_MIN']`
|
|
195
|
+
* in its own settings defaults, so a manifest is **not** a literal file and a
|
|
196
|
+
* reader that demanded one would refuse the very module whose declaration this
|
|
197
|
+
* feature exists to collect.
|
|
198
|
+
*
|
|
199
|
+
* `null` is "this module declares no environment input", which is true of most
|
|
200
|
+
* modules and is not a finding. A manifest with **no** `defineModuleManifest`
|
|
201
|
+
* call is a {@link DeclarationUnreadableError}: a module whose manifest this run
|
|
202
|
+
* cannot find is one it cannot report on, and reading that as "declares nothing"
|
|
203
|
+
* is the silent skip the estate is against (issue #113).
|
|
204
|
+
*/
|
|
205
|
+
export declare function evaluateManifestEnvDeclaration(text: string, fileName: string): readonly unknown[] | null;
|
|
206
|
+
/**
|
|
207
|
+
* The Settings-debt ledger, read off disk one shard per module
|
|
208
|
+
* (`contracts/environment-inputs.md` §4.2).
|
|
209
|
+
*
|
|
210
|
+
* Sharded because the debt is the module's: a repair that moves
|
|
211
|
+
* `INVENTORY_LOW_STOCK_RECIPIENT` into Settings touches `inventory`'s manifest
|
|
212
|
+
* and `inventory`'s shard, and nothing else. It is `check:module-boundary`'s
|
|
213
|
+
* shape, one population over.
|
|
214
|
+
*
|
|
215
|
+
* Throws rather than returning a partial answer, and every throw is a caller's
|
|
216
|
+
* exit 2: a ledger this run could not read in full is one it must not report
|
|
217
|
+
* on, because the missing half reads as *"nobody has judged this"* for one
|
|
218
|
+
* direction and as *"this entry describes nothing"* for the other — two
|
|
219
|
+
* confident findings out of one silence.
|
|
220
|
+
*/
|
|
221
|
+
export declare function loadModuleVerdictShards(directory: string): Promise<ModuleVerdictShard[]>;
|
|
222
|
+
//# sourceMappingURL=env-inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-inputs.d.ts","sourceRoot":"","sources":["../../src/rules/env-inputs.ts"],"names":[],"mappings":"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"}
|