@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,464 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL table identifiers, read out of TypeScript sources through the compiler
|
|
3
|
+
* API (feature 077, D-87).
|
|
4
|
+
*
|
|
5
|
+
* `check-module-boundary.ts` polices one rule — a module does not reach into
|
|
6
|
+
* another module's internals — through two predicates, and this file is the
|
|
7
|
+
* syntax half of the second one. The first predicate reads import specifiers
|
|
8
|
+
* (`lib/specifiers.ts`); a raw `select … from another_module_table` names no
|
|
9
|
+
* specifier at all, compiles, runs, and returns rows.
|
|
10
|
+
*
|
|
11
|
+
* Two extractions live here, and both are deliberately **syntactic only**:
|
|
12
|
+
* ownership is decided by the check, which is the file that knows what a module
|
|
13
|
+
* is.
|
|
14
|
+
*
|
|
15
|
+
* - {@link sqlTableAccesses} — the table identifiers a source *uses*, through
|
|
16
|
+
* two recognition paths: a **statement** literal, and a knex query
|
|
17
|
+
* **builder** (issue #187).
|
|
18
|
+
* - {@link declaredTableNames} — the table names a source *declares*, from an
|
|
19
|
+
* `@Entity()` class or from `create table` DDL. Both sources are needed: an
|
|
20
|
+
* owner map built from entity classes alone maps 220 tables and misses every
|
|
21
|
+
* join table and every channel bridge, which is 39 of the 157 findings the
|
|
22
|
+
* D-87 sweep measured — including the one carrying a live defect.
|
|
23
|
+
*
|
|
24
|
+
* ## Why this reads literal **nodes** and never source text
|
|
25
|
+
*
|
|
26
|
+
* The first spike for D-87 was a regex over source text. It hallucinated a dozen
|
|
27
|
+
* tables — `every`, `bumps`, `used`, `path` — because an apostrophe in an
|
|
28
|
+
* English comment opens a string literal that runs to the next apostrophe, and
|
|
29
|
+
* the prose in between parses as SQL often enough to matter. Reading
|
|
30
|
+
* `ts.StringLiteral` / template-literal nodes removes comments from the
|
|
31
|
+
* population by construction rather than by an exclusion someone has to
|
|
32
|
+
* maintain, which is why `sql-in-a-comment` is one of the check's red proofs.
|
|
33
|
+
*
|
|
34
|
+
* ## What a statement has to look like
|
|
35
|
+
*
|
|
36
|
+
* A literal joins the population when it *starts* with `select`, `insert into`,
|
|
37
|
+
* `update`, `delete from` or `with`, **and** carries the rest of that statement's
|
|
38
|
+
* skeleton: a `select` needs a `from`, an `update` needs a `set`, a `with` needs
|
|
39
|
+
* a `select`. The second half is not decoration — `'Update products in the
|
|
40
|
+
* catalog'` is English prose that a start-anchored test alone reads as an
|
|
41
|
+
* `UPDATE` against `products`, and a check that reports it teaches its readers
|
|
42
|
+
* to ignore it.
|
|
43
|
+
*
|
|
44
|
+
* ## What a builder has to look like (issue #187)
|
|
45
|
+
*
|
|
46
|
+
* A knex builder names its table as an **argument to a call**, so no statement
|
|
47
|
+
* literal exists to anchor on:
|
|
48
|
+
*
|
|
49
|
+
* ```ts
|
|
50
|
+
* await knexForStock('warehouse_channel_assignments as a')
|
|
51
|
+
* .join('warehouses as w', 'w.id', 'a.warehouse_id')
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* Both tables are `inventory`'s, read from inside `orders`' placement
|
|
55
|
+
* transaction, and both predicates were blind to them — the import predicate
|
|
56
|
+
* because a builder names no specifier, the statement path because there is no
|
|
57
|
+
* statement. **Ten** such accesses, in six files, stood outside a `sql=111` that
|
|
58
|
+
* read as the whole coupling, which is exactly the "`violations=0` licenses a
|
|
59
|
+
* package split the tree has not earned" failure D-87 exists to end. The grep
|
|
60
|
+
* that raised the issue found seven; the three it missed are the aliasing object
|
|
61
|
+
* form (`knex({ p: 'products' })`) and two reaches into **kernel** tables, which
|
|
62
|
+
* is the argument for reading nodes rather than grepping a spelling.
|
|
63
|
+
*
|
|
64
|
+
* Two shapes are recognised, and the population is bounded twice over — by the
|
|
65
|
+
* argument position and by the check's table→owner map, which only knows real
|
|
66
|
+
* tables:
|
|
67
|
+
*
|
|
68
|
+
* - **{@link TABLE_ARGUMENT_METHODS}** — a string literal in the *first*
|
|
69
|
+
* argument of `from`, `into`, `table` or a member of the join family. The
|
|
70
|
+
* list is enumerated rather than "any string on any builder method" because
|
|
71
|
+
* `where('status', …)`, `select('id')` and `orderBy(…)` take **columns**: a
|
|
72
|
+
* column spelled like another module's table would flood the ledger and the
|
|
73
|
+
* check would be switched off. Only the first argument is read, because
|
|
74
|
+
* `join(table, first, second)`'s remaining arguments are column references.
|
|
75
|
+
* - **the knex callable itself** — `knex('products')`, which starts 36 of the
|
|
76
|
+
* tree's 43 builder queries over a known table and which is not a method
|
|
77
|
+
* call at all.
|
|
78
|
+
* Its callee carries no name to key on, so the identifier must be **bound to
|
|
79
|
+
* a `getKnex()` result in the same file**; nothing else opens that door.
|
|
80
|
+
*
|
|
81
|
+
* The method list is receiver-agnostic on purpose. `Array.prototype.join` and
|
|
82
|
+
* `path.join` share the `join` spelling, and the tree calls the first 238 times;
|
|
83
|
+
* what keeps them out is that their arguments (`', '`, a path segment) are not
|
|
84
|
+
* table names in the owner map. The alternative — requiring every builder chain
|
|
85
|
+
* to root syntactically in a knex binding — would refuse them by construction
|
|
86
|
+
* but go **silently** blind on the builder held in a variable or taken as a
|
|
87
|
+
* parameter, which `catalog-admin.service.ts` and `promotion-stats-service.ts`
|
|
88
|
+
* both do. A spelling collision is a visible finding a reader resolves; a
|
|
89
|
+
* receiver rule is a miss nobody sees, and this file's whole reason for existing
|
|
90
|
+
* is that the second kind of failure is the expensive one.
|
|
91
|
+
*/
|
|
92
|
+
import ts from 'typescript';
|
|
93
|
+
/**
|
|
94
|
+
* A literal's text, with `${…}` substitutions replaced by a placeholder.
|
|
95
|
+
*
|
|
96
|
+
* A template expression is the common shape for a query with an `in (…)` list
|
|
97
|
+
* built by `ids.map(() => '?').join(',')`; splicing the spans back together
|
|
98
|
+
* keeps every table identifier around the substitution visible, which a
|
|
99
|
+
* `getText()` read would too but with the interpolation source mixed in.
|
|
100
|
+
*/
|
|
101
|
+
function literalText(node) {
|
|
102
|
+
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node))
|
|
103
|
+
return node.text;
|
|
104
|
+
if (ts.isTemplateExpression(node)) {
|
|
105
|
+
let text = node.head.text;
|
|
106
|
+
for (const span of node.templateSpans)
|
|
107
|
+
text += ` ? ${span.literal.text}`;
|
|
108
|
+
return text;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The source, parsed with parent pointers.
|
|
114
|
+
*
|
|
115
|
+
* The parents are what let the builder path walk a call chain outwards to decide
|
|
116
|
+
* whether it writes; the statement path needs only the positions.
|
|
117
|
+
*/
|
|
118
|
+
function parse(source, file) {
|
|
119
|
+
return ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true);
|
|
120
|
+
}
|
|
121
|
+
/** Every string / template literal in `sf`, with its line. */
|
|
122
|
+
function literals(sf) {
|
|
123
|
+
const found = [];
|
|
124
|
+
const visit = (node) => {
|
|
125
|
+
const text = literalText(node);
|
|
126
|
+
if (text !== null) {
|
|
127
|
+
found.push({ text, line: sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1 });
|
|
128
|
+
}
|
|
129
|
+
node.forEachChild(visit);
|
|
130
|
+
};
|
|
131
|
+
sf.forEachChild(visit);
|
|
132
|
+
return found;
|
|
133
|
+
}
|
|
134
|
+
/** `select` / `insert into` / `update` / `delete from` / `with`, at the head. */
|
|
135
|
+
const STATEMENT_HEAD = /^\s*(?:--[^\n]*\n|\s)*(select|insert\s+into|update|delete\s+from|with)\b/i;
|
|
136
|
+
/**
|
|
137
|
+
* The rest of the skeleton each head needs before the literal is read as SQL.
|
|
138
|
+
*
|
|
139
|
+
* Without this, prose scores: `'Update products in the catalog'` is an `UPDATE`
|
|
140
|
+
* against `catalog`'s `products` table to a start-anchored test.
|
|
141
|
+
*/
|
|
142
|
+
const STATEMENT_BODY = {
|
|
143
|
+
select: /\bfrom\b/i,
|
|
144
|
+
insert: /\binto\b/i,
|
|
145
|
+
update: /\bset\b/i,
|
|
146
|
+
delete: /\bfrom\b/i,
|
|
147
|
+
with: /\bselect\b/i,
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* `from` / `join` / `into` / `update` and the identifier after it.
|
|
151
|
+
*
|
|
152
|
+
* The optional `"schema".` prefix is dropped: what decides ownership is the
|
|
153
|
+
* table, and this repository has exactly one schema.
|
|
154
|
+
*/
|
|
155
|
+
const TABLE_REFERENCE = /\b(from|join|into|update)\s+(?:only\s+)?(?:"?[a-z_][a-z0-9_]*"?\.)?"?([a-z_][a-z0-9_]*)"?/gi;
|
|
156
|
+
/** `with x as (…)` — a CTE name is not a table, and may shadow one. */
|
|
157
|
+
const CTE_NAME = /\bwith\s+(?:recursive\s+)?([a-z_][a-z0-9_]*)|,\s*([a-z_][a-z0-9_]*)\s+as\s*\(/gi;
|
|
158
|
+
/** SQL keywords that follow `update` / `into` in shapes that name no table. */
|
|
159
|
+
const NOT_A_TABLE = new Set(['set', 'select', 'values', 'only', 'lateral', 'table']);
|
|
160
|
+
/**
|
|
161
|
+
* Every table identifier `source` names, through either recognition path.
|
|
162
|
+
*
|
|
163
|
+
* `file` is used for the source-file name the compiler API wants and for line
|
|
164
|
+
* numbers only; nothing here touches disk, so a caller may pass a path that does
|
|
165
|
+
* not exist. That is what lets the check's red proofs enter here, with source
|
|
166
|
+
* text, rather than below with a resolved table list.
|
|
167
|
+
*/
|
|
168
|
+
export function sqlTableAccesses(source, file) {
|
|
169
|
+
const sf = parse(source, file);
|
|
170
|
+
const found = [...statementAccesses(sf), ...builderAccesses(sf)];
|
|
171
|
+
found.sort((a, b) => a.line - b.line);
|
|
172
|
+
return found;
|
|
173
|
+
}
|
|
174
|
+
/** The tables named inside a SQL statement literal — D-87's original path. */
|
|
175
|
+
function statementAccesses(sf) {
|
|
176
|
+
const found = [];
|
|
177
|
+
for (const literal of literals(sf)) {
|
|
178
|
+
const head = STATEMENT_HEAD.exec(literal.text);
|
|
179
|
+
if (head === null)
|
|
180
|
+
continue;
|
|
181
|
+
const verb = (head[1] ?? '').trim().split(/\s+/)[0]?.toLowerCase() ?? '';
|
|
182
|
+
const body = STATEMENT_BODY[verb];
|
|
183
|
+
if (body === undefined || !body.test(literal.text))
|
|
184
|
+
continue;
|
|
185
|
+
const bound = new Set();
|
|
186
|
+
for (const match of literal.text.matchAll(CTE_NAME)) {
|
|
187
|
+
const name = match[1] ?? match[2];
|
|
188
|
+
if (name !== undefined)
|
|
189
|
+
bound.add(name.toLowerCase());
|
|
190
|
+
}
|
|
191
|
+
const statement = literal.text.replace(/\s+/g, ' ').trim().slice(0, 80);
|
|
192
|
+
const seen = new Set();
|
|
193
|
+
for (const match of literal.text.matchAll(TABLE_REFERENCE)) {
|
|
194
|
+
const keyword = (match[1] ?? '').toLowerCase();
|
|
195
|
+
const table = (match[2] ?? '').toLowerCase();
|
|
196
|
+
if (table === '' || NOT_A_TABLE.has(table) || bound.has(table))
|
|
197
|
+
continue;
|
|
198
|
+
if (seen.has(table))
|
|
199
|
+
continue;
|
|
200
|
+
seen.add(table);
|
|
201
|
+
const write = keyword === 'into' || keyword === 'update' || (verb === 'delete' && keyword === 'from');
|
|
202
|
+
found.push({
|
|
203
|
+
table,
|
|
204
|
+
direction: write ? 'write' : 'read',
|
|
205
|
+
syntax: 'statement',
|
|
206
|
+
line: literal.line,
|
|
207
|
+
statement,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return found;
|
|
212
|
+
}
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// The knex query builder (issue #187)
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
/**
|
|
217
|
+
* Builder methods whose **first** argument names a table.
|
|
218
|
+
*
|
|
219
|
+
* Enumerated, and this is the list the header argues for: `where`, `select`,
|
|
220
|
+
* `orderBy`, `count` and the rest take **columns**, so matching any string
|
|
221
|
+
* literal on any builder method would report a column spelled like another
|
|
222
|
+
* module's table and the ledger would fill with noise. The tree calls four of
|
|
223
|
+
* these today (`from`, `join`, `leftJoin`, `innerJoin`); the other join variants
|
|
224
|
+
* are the same knex surface, and leaving one out would make the day somebody
|
|
225
|
+
* writes `rightJoin` the day the check goes quietly blind.
|
|
226
|
+
*/
|
|
227
|
+
const TABLE_ARGUMENT_METHODS = new Set([
|
|
228
|
+
'from',
|
|
229
|
+
'into',
|
|
230
|
+
'table',
|
|
231
|
+
'join',
|
|
232
|
+
'innerJoin',
|
|
233
|
+
'leftJoin',
|
|
234
|
+
'leftOuterJoin',
|
|
235
|
+
'rightJoin',
|
|
236
|
+
'rightOuterJoin',
|
|
237
|
+
'fullOuterJoin',
|
|
238
|
+
'crossJoin',
|
|
239
|
+
]);
|
|
240
|
+
/**
|
|
241
|
+
* Builder methods that move rows, anywhere in the chain the table is named in.
|
|
242
|
+
*
|
|
243
|
+
* `into` is here as well as in {@link TABLE_ARGUMENT_METHODS} because
|
|
244
|
+
* `knex.insert(rows).into('x')` names the table on the write method itself.
|
|
245
|
+
*/
|
|
246
|
+
const WRITE_METHODS = new Set([
|
|
247
|
+
'insert',
|
|
248
|
+
'update',
|
|
249
|
+
'delete',
|
|
250
|
+
'del',
|
|
251
|
+
'upsert',
|
|
252
|
+
'truncate',
|
|
253
|
+
'increment',
|
|
254
|
+
'decrement',
|
|
255
|
+
'into',
|
|
256
|
+
]);
|
|
257
|
+
/**
|
|
258
|
+
* `em.getKnex()`, `em.getConnection().getKnex()`, `this.emFactory().getKnex()`.
|
|
259
|
+
*
|
|
260
|
+
* Exported because `check-transaction-context` refuses the same handle for a
|
|
261
|
+
* different reason (issue #200: it carries no transaction context), and two
|
|
262
|
+
* copies of "what a knex handle looks like" would drift — the receiver is
|
|
263
|
+
* spelled at least three ways in this tree already.
|
|
264
|
+
*/
|
|
265
|
+
export function isGetKnexCall(node) {
|
|
266
|
+
return (ts.isCallExpression(node) &&
|
|
267
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
268
|
+
node.expression.name.text === 'getKnex');
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* The identifiers this file binds to a knex instance.
|
|
272
|
+
*
|
|
273
|
+
* The knex callable is `knex('products')` — a call whose callee carries no
|
|
274
|
+
* method name to key on — so the only structural evidence available is the
|
|
275
|
+
* binding, and the tree writes exactly one shape for it — a `const` initialised
|
|
276
|
+
* from a `getKnex()` call, 32 times: `knex` in 30 of them, `knexForStock` and
|
|
277
|
+
* `knexEmpty` in the other two. Keying on the binding rather than on the
|
|
278
|
+
* identifier's spelling keeps the rule a property of the code and not of what
|
|
279
|
+
* somebody named a variable.
|
|
280
|
+
*/
|
|
281
|
+
function knexBindings(sf) {
|
|
282
|
+
const bound = new Set();
|
|
283
|
+
const visit = (node) => {
|
|
284
|
+
if (ts.isVariableDeclaration(node) &&
|
|
285
|
+
ts.isIdentifier(node.name) &&
|
|
286
|
+
node.initializer !== undefined &&
|
|
287
|
+
isGetKnexCall(node.initializer)) {
|
|
288
|
+
bound.add(node.name.text);
|
|
289
|
+
}
|
|
290
|
+
node.forEachChild(visit);
|
|
291
|
+
};
|
|
292
|
+
sf.forEachChild(visit);
|
|
293
|
+
return bound;
|
|
294
|
+
}
|
|
295
|
+
/** The table a builder argument names, or `null` when it names no table. */
|
|
296
|
+
function builderTableName(text) {
|
|
297
|
+
// `'warehouses as w'` — knex's alias form, and the one `order-service.ts`
|
|
298
|
+
// writes. Everything after the alias keyword belongs to the alias.
|
|
299
|
+
const withoutAlias = text.split(/\s+as\s+/i)[0] ?? '';
|
|
300
|
+
const bare = withoutAlias.trim().replace(/^"(.*)"$/, '$1');
|
|
301
|
+
// `"public".products` / `w.id` — the qualifier is dropped for the same reason
|
|
302
|
+
// the statement path drops it: this repository has one schema, and what is
|
|
303
|
+
// left of a column reference (`id`) is not a table name in the owner map.
|
|
304
|
+
const unqualified = bare.includes('.') ? (bare.split('.').pop() ?? '') : bare;
|
|
305
|
+
const table = unqualified.toLowerCase();
|
|
306
|
+
return /^[a-z_][a-z0-9_]*$/.test(table) ? table : null;
|
|
307
|
+
}
|
|
308
|
+
/** Every table a call argument names: a string literal, or an alias object's values. */
|
|
309
|
+
function tableArguments(argument) {
|
|
310
|
+
if (argument === undefined)
|
|
311
|
+
return [];
|
|
312
|
+
const text = ts.isStringLiteral(argument) || ts.isNoSubstitutionTemplateLiteral(argument)
|
|
313
|
+
? argument.text
|
|
314
|
+
: null;
|
|
315
|
+
if (text !== null) {
|
|
316
|
+
const table = builderTableName(text);
|
|
317
|
+
return table === null ? [] : [table];
|
|
318
|
+
}
|
|
319
|
+
// `knex({ p: 'products' })` — the alias is the key and the table is the value.
|
|
320
|
+
if (!ts.isObjectLiteralExpression(argument))
|
|
321
|
+
return [];
|
|
322
|
+
const tables = [];
|
|
323
|
+
for (const property of argument.properties) {
|
|
324
|
+
if (!ts.isPropertyAssignment(property))
|
|
325
|
+
continue;
|
|
326
|
+
if (!ts.isStringLiteral(property.initializer))
|
|
327
|
+
continue;
|
|
328
|
+
const table = builderTableName(property.initializer.text);
|
|
329
|
+
if (table !== null)
|
|
330
|
+
tables.push(table);
|
|
331
|
+
}
|
|
332
|
+
return tables;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* The outermost call chain `node` sits in.
|
|
336
|
+
*
|
|
337
|
+
* `knex('x').where(…).update(…)` is one expression, and the write method can sit
|
|
338
|
+
* on either side of the table: `update` follows it and `insert` precedes it in
|
|
339
|
+
* `knex.insert(rows).into('x')`. Walking out to the whole chain and then reading
|
|
340
|
+
* every method name in it answers both without a rule per shape.
|
|
341
|
+
*/
|
|
342
|
+
function outermostChain(node) {
|
|
343
|
+
let current = node;
|
|
344
|
+
for (;;) {
|
|
345
|
+
const parent = current.parent;
|
|
346
|
+
if (parent === undefined)
|
|
347
|
+
return current;
|
|
348
|
+
if (ts.isPropertyAccessExpression(parent) && parent.expression === current)
|
|
349
|
+
current = parent;
|
|
350
|
+
else if (ts.isCallExpression(parent) && parent.expression === current)
|
|
351
|
+
current = parent;
|
|
352
|
+
else
|
|
353
|
+
return current;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/** Whether any method in the chain moves rows. */
|
|
357
|
+
function chainWrites(chain) {
|
|
358
|
+
let writes = false;
|
|
359
|
+
const visit = (node) => {
|
|
360
|
+
if (writes)
|
|
361
|
+
return;
|
|
362
|
+
if (ts.isPropertyAccessExpression(node) && WRITE_METHODS.has(node.name.text))
|
|
363
|
+
writes = true;
|
|
364
|
+
node.forEachChild(visit);
|
|
365
|
+
};
|
|
366
|
+
visit(chain);
|
|
367
|
+
return writes;
|
|
368
|
+
}
|
|
369
|
+
/** Every table a knex query builder in `sf` names. */
|
|
370
|
+
function builderAccesses(sf) {
|
|
371
|
+
const bound = knexBindings(sf);
|
|
372
|
+
const found = [];
|
|
373
|
+
const visit = (node) => {
|
|
374
|
+
if (ts.isCallExpression(node)) {
|
|
375
|
+
const callee = node.expression;
|
|
376
|
+
// A table-taking builder method, or the knex callable itself. Either way
|
|
377
|
+
// only the **first** argument is read: `join(table, first, second)`'s
|
|
378
|
+
// remaining arguments are column references.
|
|
379
|
+
const namesATable = (ts.isPropertyAccessExpression(callee) && TABLE_ARGUMENT_METHODS.has(callee.name.text)) ||
|
|
380
|
+
(ts.isIdentifier(callee) && bound.has(callee.text)) ||
|
|
381
|
+
isGetKnexCall(callee);
|
|
382
|
+
const named = namesATable ? tableArguments(node.arguments[0]) : [];
|
|
383
|
+
if (named.length > 0) {
|
|
384
|
+
const chain = outermostChain(node);
|
|
385
|
+
const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
|
|
386
|
+
const statement = chain.getText(sf).replace(/\s+/g, ' ').trim().slice(0, 80);
|
|
387
|
+
const direction = chainWrites(chain) ? 'write' : 'read';
|
|
388
|
+
for (const table of named) {
|
|
389
|
+
found.push({ table, direction, syntax: 'builder', line, statement });
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
node.forEachChild(visit);
|
|
394
|
+
};
|
|
395
|
+
sf.forEachChild(visit);
|
|
396
|
+
return found;
|
|
397
|
+
}
|
|
398
|
+
/** `create table "x"` / `create table if not exists x`, inside a SQL literal. */
|
|
399
|
+
const CREATE_TABLE = /\bcreate\s+table\s+(?:if\s+not\s+exists\s+)?"?([a-z_][a-z0-9_]*)"?/gi;
|
|
400
|
+
/**
|
|
401
|
+
* The table names `source` declares, from either owner-map source.
|
|
402
|
+
*
|
|
403
|
+
* An `@Entity()` class declares its `tableName` option, or — for the classes
|
|
404
|
+
* that do not set one — the name `PluralizingNamingStrategy` derives from the
|
|
405
|
+
* class name, imported rather than reimplemented so the two cannot drift.
|
|
406
|
+
* `create table` DDL is read out of the same literal nodes as everything else,
|
|
407
|
+
* so a migration that mentions a table in a comment declares nothing.
|
|
408
|
+
*/
|
|
409
|
+
export function declaredTableNames(source, file, tableNameOf) {
|
|
410
|
+
const found = [];
|
|
411
|
+
const seen = new Set();
|
|
412
|
+
const add = (table, from) => {
|
|
413
|
+
if (seen.has(table))
|
|
414
|
+
return;
|
|
415
|
+
seen.add(table);
|
|
416
|
+
found.push({ table, source: from });
|
|
417
|
+
};
|
|
418
|
+
const sf = parse(source, file);
|
|
419
|
+
if (source.includes('@Entity')) {
|
|
420
|
+
const visit = (node) => {
|
|
421
|
+
if (ts.isClassDeclaration(node) && ts.canHaveDecorators(node)) {
|
|
422
|
+
for (const decorator of ts.getDecorators(node) ?? []) {
|
|
423
|
+
const call = decorator.expression;
|
|
424
|
+
if (!ts.isCallExpression(call))
|
|
425
|
+
continue;
|
|
426
|
+
if (!ts.isIdentifier(call.expression) || call.expression.text !== 'Entity')
|
|
427
|
+
continue;
|
|
428
|
+
const declared = entityTableName(call);
|
|
429
|
+
if (declared !== null)
|
|
430
|
+
add(declared, 'entity');
|
|
431
|
+
else if (node.name)
|
|
432
|
+
add(tableNameOf(node.name.text), 'entity');
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
node.forEachChild(visit);
|
|
436
|
+
};
|
|
437
|
+
sf.forEachChild(visit);
|
|
438
|
+
}
|
|
439
|
+
for (const literal of literals(sf)) {
|
|
440
|
+
for (const match of literal.text.matchAll(CREATE_TABLE)) {
|
|
441
|
+
const table = match[1];
|
|
442
|
+
if (table !== undefined)
|
|
443
|
+
add(table.toLowerCase(), 'migration');
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return found;
|
|
447
|
+
}
|
|
448
|
+
/** The `tableName` option of an `@Entity({ … })` call, when it sets one. */
|
|
449
|
+
function entityTableName(call) {
|
|
450
|
+
const [argument] = call.arguments;
|
|
451
|
+
if (argument === undefined || !ts.isObjectLiteralExpression(argument))
|
|
452
|
+
return null;
|
|
453
|
+
for (const property of argument.properties) {
|
|
454
|
+
if (!ts.isPropertyAssignment(property))
|
|
455
|
+
continue;
|
|
456
|
+
const name = ts.isIdentifier(property.name) ? property.name.text : null;
|
|
457
|
+
if (name !== 'tableName')
|
|
458
|
+
continue;
|
|
459
|
+
if (ts.isStringLiteral(property.initializer))
|
|
460
|
+
return property.initializer.text;
|
|
461
|
+
}
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
//# sourceMappingURL=sql-tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-tables.js","sourceRoot":"","sources":["../../src/lib/sql-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAqC5B;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,IAAa;IAChC,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,+BAA+B,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC3F,IAAI,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa;YAAE,IAAI,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACzE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAS,KAAK,CAAC,MAAc,EAAE,IAAY;IACzC,OAAO,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACzE,CAAC;AAED,8DAA8D;AAC9D,SAAS,QAAQ,CAAC,EAAiB;IACjC,MAAM,KAAK,GAA0C,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,CAAC;IACF,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,MAAM,cAAc,GAAG,2EAA2E,CAAC;AAEnG;;;;;GAKG;AACH,MAAM,cAAc,GAAqC;IACvD,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,WAAW;IACnB,IAAI,EAAE,aAAa;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,eAAe,GACnB,6FAA6F,CAAC;AAEhG,uEAAuE;AACvE,MAAM,QAAQ,GAAG,iFAAiF,CAAC;AAEnG,+EAA+E;AAC/E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAErF;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,IAAY;IAC3D,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,iBAAiB,CAAC,EAAE,CAAC,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,SAAS,iBAAiB,CAAC,EAAiB;IAC1C,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QAC5B,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QACzE,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,SAAS;QAE7D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,IAAI,KAAK,SAAS;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YAC3D,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7C,IAAI,KAAK,KAAK,EAAE,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YACzE,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChB,MAAM,KAAK,GACT,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,QAAQ,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC;YAC1F,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK;gBACL,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;gBACnC,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,SAAS;aACV,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,sCAAsC;AACtC,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACrC,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,WAAW;IACX,UAAU;IACV,eAAe;IACf,WAAW;IACX,gBAAgB;IAChB,eAAe;IACf,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,UAAU;IACV,WAAW;IACX,WAAW;IACX,MAAM;CACP,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,IAAmB;IAC/C,OAAO,CACL,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;QACzB,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,UAAU,CAAC;QAC9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CACxC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,YAAY,CAAC,EAAiB;IACrC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,IACE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC;YAC9B,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1B,IAAI,CAAC,WAAW,KAAK,SAAS;YAC9B,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,EAC/B,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,CAAC;IACF,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4EAA4E;AAC5E,SAAS,gBAAgB,CAAC,IAAY;IACpC,0EAA0E;IAC1E,mEAAmE;IACnE,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC3D,8EAA8E;IAC9E,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IACxC,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACzD,CAAC;AAED,wFAAwF;AACxF,SAAS,cAAc,CAAC,QAAmC;IACzD,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,+BAA+B,CAAC,QAAQ,CAAC;QACvF,CAAC,CAAC,QAAQ,CAAC,IAAI;QACf,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IACD,+EAA+E;IAC/E,IAAI,CAAC,EAAE,CAAC,yBAAyB,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IACvD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;YAAE,SAAS;QACjD,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,SAAS;QACxD,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,IAAa;IACnC,IAAI,OAAO,GAAY,IAAI,CAAC;IAC5B,SAAS,CAAC;QACR,MAAM,MAAM,GAAwB,OAAO,CAAC,MAAM,CAAC;QACnD,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC;QACzC,IAAI,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO;YAAE,OAAO,GAAG,MAAM,CAAC;aACxF,IAAI,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO;YAAE,OAAO,GAAG,MAAM,CAAC;;YACnF,OAAO,OAAO,CAAC;IACtB,CAAC;AACH,CAAC;AAED,kDAAkD;AAClD,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,IAAI,MAAM;YAAE,OAAO;QACnB,IAAI,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,GAAG,IAAI,CAAC;QAC5F,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,CAAC;IACF,KAAK,CAAC,KAAK,CAAC,CAAC;IACb,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,sDAAsD;AACtD,SAAS,eAAe,CAAC,EAAiB;IACxC,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAqB,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;YAC/B,yEAAyE;YACzE,sEAAsE;YACtE,6CAA6C;YAC7C,MAAM,WAAW,GACf,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvF,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACnD,aAAa,CAAC,MAAM,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;gBACnC,MAAM,IAAI,GAAG,EAAE,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBAC1E,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7E,MAAM,SAAS,GAAuB,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC5E,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;oBAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,CAAC;IACF,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,MAAM,YAAY,GAAG,sEAAsE,CAAC;AAkB5F;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAc,EACd,IAAY,EACZ,WAAoC;IAEpC,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,IAA4B,EAAQ,EAAE;QAChE,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO;QAC5B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;YACpC,IAAI,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9D,KAAK,MAAM,SAAS,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;oBACrD,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC;oBAClC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;wBAAE,SAAS;oBACzC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,QAAQ;wBAAE,SAAS;oBACrF,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;oBACvC,IAAI,QAAQ,KAAK,IAAI;wBAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;yBAC1C,IAAI,IAAI,CAAC,IAAI;wBAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC,CAAC;QACF,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACxD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,KAAK,KAAK,SAAS;gBAAE,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,WAAW,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4EAA4E;AAC5E,SAAS,eAAe,CAAC,IAAuB;IAC9C,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IAClC,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC,yBAAyB,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACnF,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;YAAE,SAAS;QACjD,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACxE,IAAI,IAAI,KAAK,WAAW;YAAE,SAAS;QACnC,IAAI,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;IACjF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The part of a manifest this derivation reads. Structural rather than
|
|
3
|
+
* `ModuleManifest`, so a fixture can supply the two fields it looks at and
|
|
4
|
+
* nothing else.
|
|
5
|
+
*/
|
|
6
|
+
export interface ManifestActivationInput {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly activation?: {
|
|
9
|
+
readonly settingCode?: string;
|
|
10
|
+
readonly default?: boolean;
|
|
11
|
+
readonly nonDeactivatable?: boolean;
|
|
12
|
+
readonly reason?: string;
|
|
13
|
+
} | undefined;
|
|
14
|
+
}
|
|
15
|
+
/** Raised when the manifest index could not be read, or read as empty. */
|
|
16
|
+
export declare class ManifestIndexUnreadableError extends Error {
|
|
17
|
+
readonly name = "ManifestIndexUnreadableError";
|
|
18
|
+
}
|
|
19
|
+
/** The modules the orchestrator refuses to switch off, on either axis. */
|
|
20
|
+
export declare function lockedOwners(manifests: readonly ManifestActivationInput[]): ReadonlySet<string>;
|
|
21
|
+
/** A module an operator can switch off — the complement of the locked set. */
|
|
22
|
+
export declare function isSwitchableModule(moduleId: string, locked: ReadonlySet<string>): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Read the manifests out of the generated index at `indexPath`.
|
|
25
|
+
*
|
|
26
|
+
* **The path is given, never built** (feature 080, T040a). It used to be
|
|
27
|
+
* `join(srcRoot, 'modules/_lifecycle/manifest-index.generated.ts')` — the
|
|
28
|
+
* module tree's location spelled out inside the one derivation whose job is to
|
|
29
|
+
* make that location a fact rather than a constant, so a layout move broke the
|
|
30
|
+
* reader every check's population floor rests on. `lib/module-roots.ts` locates
|
|
31
|
+
* it by search over the workspace members and hands it here.
|
|
32
|
+
*
|
|
33
|
+
* Throws `ManifestIndexUnreadableError` when the index is missing or empty; a
|
|
34
|
+
* caller turns that into exit 2, never into a pass.
|
|
35
|
+
*/
|
|
36
|
+
export declare function loadManifestActivations(indexPath: string): Promise<readonly ManifestActivationInput[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Where each registered module's manifest actually is, straight from the index.
|
|
39
|
+
*
|
|
40
|
+
* The index records it (feature 080, T041a) because a module's own directory is
|
|
41
|
+
* `dirname` of it, and three origins answer differently: a module in the
|
|
42
|
+
* application tree with `<src>/modules/<id>/manifest.ts`, a packaged one with
|
|
43
|
+
* its `package.json`, and — since T040b — the one module the host itself owns,
|
|
44
|
+
* whose directory is neither. `lib/module-roots.ts` reads this to place that
|
|
45
|
+
* last one, rather than inferring it from a directory that is deliberately not
|
|
46
|
+
* named after its module id.
|
|
47
|
+
*
|
|
48
|
+
* Same reader and same import as {@link loadManifestActivations}, so the two
|
|
49
|
+
* cannot come to disagree about which modules exist or where they are.
|
|
50
|
+
*/
|
|
51
|
+
export declare function loadManifestLocations(indexPath: string): Promise<ReadonlyMap<string, string>>;
|
|
52
|
+
/** The locked set, straight from the generated index. */
|
|
53
|
+
export declare function loadLockedOwners(indexPath: string): Promise<ReadonlySet<string>>;
|
|
54
|
+
//# sourceMappingURL=switchable-modules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switchable-modules.d.ts","sourceRoot":"","sources":["../../src/lib/switchable-modules.ts"],"names":[],"mappings":"AA0BA;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,CAAC,EAChB;QACE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;QACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,GACD,SAAS,CAAC;CACf;AAED,0EAA0E;AAC1E,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,SAAkB,IAAI,kCAAkC;CACzD;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAC1B,SAAS,EAAE,SAAS,uBAAuB,EAAE,GAC5C,WAAW,CAAC,MAAM,CAAC,CAMrB;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAEzF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,SAAS,uBAAuB,EAAE,CAAC,CAiB7C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAetC;AAED,yDAAyD;AACzD,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAEtF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one derivation of "can an operator switch this module off?" (D-63/D-68).
|
|
3
|
+
*
|
|
4
|
+
* Two checks need it and neither may own it. `check-port-catches` reports a
|
|
5
|
+
* `catch` as `OWNER LOCKED` when every gate it swallows belongs to a module the
|
|
6
|
+
* orchestrator refuses to switch off; `check-entry-presence` leaves such a
|
|
7
|
+
* module's boot hooks out of its population, because a hook cannot fail to
|
|
8
|
+
* decide a presence that has no off state. Both answers rest on the same fact —
|
|
9
|
+
* the module's manifest declares `activation.nonDeactivatable` — and both are
|
|
10
|
+
* only safe if the fact is **read at check time** rather than written down: an
|
|
11
|
+
* owner who withdraws a lock must re-red every site that was resting on it, in
|
|
12
|
+
* the same run, with no ledger to edit. A hand-maintained list would go stale
|
|
13
|
+
* silently, which is the failure mode two-way ledgers exist to prevent. D-68
|
|
14
|
+
* says so explicitly — "the two checks share one helper in
|
|
15
|
+
* `backend/scripts/lib/`" — and this is that helper.
|
|
16
|
+
*
|
|
17
|
+
* `lockedOwners` is pure and takes the manifests, so each check's red proofs can
|
|
18
|
+
* drive the classification from a fixture that enters at the top of the
|
|
19
|
+
* analysis. `loadLockedOwners` is the one place that knows where the generated
|
|
20
|
+
* index lives; it **refuses an empty index** rather than returning an empty set,
|
|
21
|
+
* because "no module is locked" and "the index did not load" would otherwise be
|
|
22
|
+
* the same answer — and the second silently changes both checks' verdicts while
|
|
23
|
+
* looking like a normal run (issue #113).
|
|
24
|
+
*/
|
|
25
|
+
import { pathToFileURL } from 'node:url';
|
|
26
|
+
/** Raised when the manifest index could not be read, or read as empty. */
|
|
27
|
+
export class ManifestIndexUnreadableError extends Error {
|
|
28
|
+
name = 'ManifestIndexUnreadableError';
|
|
29
|
+
}
|
|
30
|
+
/** The modules the orchestrator refuses to switch off, on either axis. */
|
|
31
|
+
export function lockedOwners(manifests) {
|
|
32
|
+
return new Set(manifests
|
|
33
|
+
.filter((manifest) => manifest.activation?.nonDeactivatable === true)
|
|
34
|
+
.map((manifest) => manifest.id));
|
|
35
|
+
}
|
|
36
|
+
/** A module an operator can switch off — the complement of the locked set. */
|
|
37
|
+
export function isSwitchableModule(moduleId, locked) {
|
|
38
|
+
return !locked.has(moduleId);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Read the manifests out of the generated index at `indexPath`.
|
|
42
|
+
*
|
|
43
|
+
* **The path is given, never built** (feature 080, T040a). It used to be
|
|
44
|
+
* `join(srcRoot, 'modules/_lifecycle/manifest-index.generated.ts')` — the
|
|
45
|
+
* module tree's location spelled out inside the one derivation whose job is to
|
|
46
|
+
* make that location a fact rather than a constant, so a layout move broke the
|
|
47
|
+
* reader every check's population floor rests on. `lib/module-roots.ts` locates
|
|
48
|
+
* it by search over the workspace members and hands it here.
|
|
49
|
+
*
|
|
50
|
+
* Throws `ManifestIndexUnreadableError` when the index is missing or empty; a
|
|
51
|
+
* caller turns that into exit 2, never into a pass.
|
|
52
|
+
*/
|
|
53
|
+
export async function loadManifestActivations(indexPath) {
|
|
54
|
+
let entries;
|
|
55
|
+
try {
|
|
56
|
+
const loaded = (await import(pathToFileURL(indexPath).href));
|
|
57
|
+
entries = loaded.DISCOVERED_MANIFESTS ?? [];
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
throw new ManifestIndexUnreadableError(`${indexPath} could not be imported: ${String(err)}`);
|
|
61
|
+
}
|
|
62
|
+
if (entries.length === 0) {
|
|
63
|
+
throw new ManifestIndexUnreadableError(`${indexPath} declared no modules`);
|
|
64
|
+
}
|
|
65
|
+
return entries.map((entry) => ({
|
|
66
|
+
id: entry.id,
|
|
67
|
+
activation: entry.manifest.activation,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Where each registered module's manifest actually is, straight from the index.
|
|
72
|
+
*
|
|
73
|
+
* The index records it (feature 080, T041a) because a module's own directory is
|
|
74
|
+
* `dirname` of it, and three origins answer differently: a module in the
|
|
75
|
+
* application tree with `<src>/modules/<id>/manifest.ts`, a packaged one with
|
|
76
|
+
* its `package.json`, and — since T040b — the one module the host itself owns,
|
|
77
|
+
* whose directory is neither. `lib/module-roots.ts` reads this to place that
|
|
78
|
+
* last one, rather than inferring it from a directory that is deliberately not
|
|
79
|
+
* named after its module id.
|
|
80
|
+
*
|
|
81
|
+
* Same reader and same import as {@link loadManifestActivations}, so the two
|
|
82
|
+
* cannot come to disagree about which modules exist or where they are.
|
|
83
|
+
*/
|
|
84
|
+
export async function loadManifestLocations(indexPath) {
|
|
85
|
+
let entries;
|
|
86
|
+
try {
|
|
87
|
+
const loaded = (await import(pathToFileURL(indexPath).href));
|
|
88
|
+
entries = loaded.DISCOVERED_MANIFESTS ?? [];
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
throw new ManifestIndexUnreadableError(`${indexPath} could not be imported: ${String(err)}`);
|
|
92
|
+
}
|
|
93
|
+
const located = new Map();
|
|
94
|
+
for (const entry of entries) {
|
|
95
|
+
if (entry.manifestPath !== undefined)
|
|
96
|
+
located.set(entry.id, entry.manifestPath);
|
|
97
|
+
}
|
|
98
|
+
return located;
|
|
99
|
+
}
|
|
100
|
+
/** The locked set, straight from the generated index. */
|
|
101
|
+
export async function loadLockedOwners(indexPath) {
|
|
102
|
+
return lockedOwners(await loadManifestActivations(indexPath));
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=switchable-modules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switchable-modules.js","sourceRoot":"","sources":["../../src/lib/switchable-modules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAmBzC,0EAA0E;AAC1E,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACnC,IAAI,GAAG,8BAA8B,CAAC;CACzD;AAED,0EAA0E;AAC1E,MAAM,UAAU,YAAY,CAC1B,SAA6C;IAE7C,OAAO,IAAI,GAAG,CACZ,SAAS;SACN,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;SACpE,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAClC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,MAA2B;IAC9E,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,SAAiB;IAEjB,IAAI,OAA0E,CAAC;IAC/E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAE1D,CAAC;QACF,OAAO,GAAG,MAAM,CAAC,oBAAoB,IAAI,EAAE,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,IAAI,4BAA4B,CAAC,GAAG,SAAS,2BAA2B,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,4BAA4B,CAAC,GAAG,SAAS,sBAAsB,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAmD;KAC/E,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAiB;IAEjB,IAAI,OAA6D,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAE1D,CAAC;QACF,OAAO,GAAG,MAAM,CAAC,oBAAoB,IAAI,EAAE,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,IAAI,4BAA4B,CAAC,GAAG,SAAS,2BAA2B,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IACtD,OAAO,YAAY,CAAC,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC;AAChE,CAAC"}
|