@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,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entity index — one host's answer to *"which modules did I install, and
|
|
3
|
+
* which entity classes did each of them publish?"*
|
|
4
|
+
* (`specs/109-backend-test-kit/tasks.md` T065).
|
|
5
|
+
*
|
|
6
|
+
* ## Why a generated artefact and not a package
|
|
7
|
+
*
|
|
8
|
+
* A server-bound test writes rows, and to write one it needs the entity class
|
|
9
|
+
* **the ORM registered**: a structurally identical copy read out of a package's
|
|
10
|
+
* source is a class the ORM never discovered, and `em.find` against it answers
|
|
11
|
+
* with nothing (D-160.6, D-160.6.1). A module package publishes one `entities`
|
|
12
|
+
* array and **no entity class by name** (D-168), so the class is picked out of
|
|
13
|
+
* that array by name — `@endora-commerce/test-kit/support`'s `entityNamedIn`,
|
|
14
|
+
* which is the lookup half and holds no population.
|
|
15
|
+
*
|
|
16
|
+
* The population is where this has to be a generated file. *Which modules one
|
|
17
|
+
* deployment installed* is the single fact a package that may name no module is
|
|
18
|
+
* forbidden to know (109 R2.2, FR-001), which is why
|
|
19
|
+
* `backend/test/helpers/package-entities.ts` is permanently host-owned and may
|
|
20
|
+
* neither move into a module package nor be published by the kit
|
|
21
|
+
* (`specs/084-small-f4-package-layout/contracts/module-package-layout.md` R10's
|
|
22
|
+
* closing paragraph — *"do not re-open this on volume"*). This file is the
|
|
23
|
+
* successor that paragraph names: the per-host artefact that gives a
|
|
24
|
+
* **stranger's** host the same index, derived from their install rather than
|
|
25
|
+
* from ours.
|
|
26
|
+
*
|
|
27
|
+
* ## One derivation, two populations
|
|
28
|
+
*
|
|
29
|
+
* `contracts/instance-repository.md` R3.5, exactly as `admin-artefacts.ts` is
|
|
30
|
+
* shared: `endora generate` renders it over the packages an instance installed,
|
|
31
|
+
* and `composer:generate` renders it over this repository's workspace members.
|
|
32
|
+
* A second implementation inside either host would be two answers to one
|
|
33
|
+
* question — and the one this repository holds would be the one nobody outside
|
|
34
|
+
* could correct.
|
|
35
|
+
*
|
|
36
|
+
* ## What it deliberately does not import, and the annotation that is not optional
|
|
37
|
+
*
|
|
38
|
+
* Nothing but the installed modules. A `satisfies InstalledEntityIndex` would
|
|
39
|
+
* read better and would put a type-only import of `@endora-commerce/test-kit`
|
|
40
|
+
* into a file **every** instance renders, including the overwhelming majority
|
|
41
|
+
* that run no test and never install the kit — an unresolvable specifier the
|
|
42
|
+
* first time such a client compiles the file. The shape is checked where it is
|
|
43
|
+
* used, at `entityNamedIn`'s argument position, by the consumer that needs it.
|
|
44
|
+
*
|
|
45
|
+
* The export is nevertheless **annotated**, with a type the file declares itself,
|
|
46
|
+
* and that is a measurement rather than a style: left inferred, `tsc` answers
|
|
47
|
+
* **TS2742** — *"the inferred type of `installedModuleEntities` cannot be named
|
|
48
|
+
* without a reference to `../node_modules/@endora-commerce/mod-…/dist/backend/
|
|
49
|
+
* entities/….entity`"* — once per entity class in the whole install, because the
|
|
50
|
+
* inferred type is a tuple of classes declared inside packages whose paths the
|
|
51
|
+
* consumer cannot name. The annotation is structurally the kit's
|
|
52
|
+
* `InstalledEntityIndex` and loses nothing a caller uses: `entityNamedIn` takes
|
|
53
|
+
* the module id as a **string**, so per-key precision has no reader.
|
|
54
|
+
*/
|
|
55
|
+
import { type ModulePackage } from './module-packages.js';
|
|
56
|
+
/** The symbol the artefact exports, named once so every consumer agrees. */
|
|
57
|
+
export declare const ENTITY_INDEX_EXPORT = "installedModuleEntities";
|
|
58
|
+
/** One installed module, as the index names it. */
|
|
59
|
+
export interface EntityIndexEntry {
|
|
60
|
+
/** `endora.id`, the identity of record (D-142) — the index's key. */
|
|
61
|
+
readonly moduleId: string;
|
|
62
|
+
/** The bare specifier of its published `./backend`. */
|
|
63
|
+
readonly specifier: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Every installed module package, sorted by module id.
|
|
67
|
+
*
|
|
68
|
+
* **A module that publishes no `./backend` is refused, not skipped.** A skip is
|
|
69
|
+
* how a whole module goes missing from an index without a word, and the failure
|
|
70
|
+
* then lands on whichever test asked for one of its entities — as
|
|
71
|
+
* `ModuleNotInstalledError` for a module the client did install, which sends
|
|
72
|
+
* them to look at their install instead of at the artefact. It is the same
|
|
73
|
+
* reason `collectAdminContributions` refuses a package whose admin layer no
|
|
74
|
+
* subpath covers.
|
|
75
|
+
*
|
|
76
|
+
* There is no *"has entities"* predicate and there deliberately cannot be one:
|
|
77
|
+
* whether the array is empty is a runtime fact about a package's JavaScript, and
|
|
78
|
+
* a generator that imported every installed module to find out would evaluate a
|
|
79
|
+
* client's whole backend to render a test artefact. Seven of this repository's
|
|
80
|
+
* own module packages publish an empty array, and an empty array in the index is
|
|
81
|
+
* the correct, loud answer — `entityNamed` names every class the array does
|
|
82
|
+
* declare, `(empty)` included.
|
|
83
|
+
*/
|
|
84
|
+
export declare function collectEntityIndexEntries(packages: readonly ModulePackage[]): readonly EntityIndexEntry[];
|
|
85
|
+
/** Where the artefact lands, relative to the workspace root a host owns. */
|
|
86
|
+
export declare function entityIndexOutputPathIn(root: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* The "do not edit" header **this repository's own** generator writes, and the
|
|
89
|
+
* default for the same reason `emitAdminRegistry`'s is: an instance's own header
|
|
90
|
+
* says something different, and it passes it in.
|
|
91
|
+
*/
|
|
92
|
+
export declare const COMPOSER_ENTITY_INDEX_HEADER: string;
|
|
93
|
+
/** Pure render of the entity index, exported so a test can drive it. */
|
|
94
|
+
export declare function emitEntityIndex(entries: readonly EntityIndexEntry[], header?: string): string;
|
|
95
|
+
//# sourceMappingURL=entity-index-artefact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-index-artefact.d.ts","sourceRoot":"","sources":["../../src/lib/entity-index-artefact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAiB9E,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,4BAA4B,CAAC;AAE7D,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,aAAa,EAAE,GACjC,SAAS,gBAAgB,EAAE,CAoB7B;AAED,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ5D;AAYD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAIK,CAAC;AAE/C,wEAAwE;AACxE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,MAAM,GAAE,MAAqC,GAC5C,MAAM,CA2ER"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entity index — one host's answer to *"which modules did I install, and
|
|
3
|
+
* which entity classes did each of them publish?"*
|
|
4
|
+
* (`specs/109-backend-test-kit/tasks.md` T065).
|
|
5
|
+
*
|
|
6
|
+
* ## Why a generated artefact and not a package
|
|
7
|
+
*
|
|
8
|
+
* A server-bound test writes rows, and to write one it needs the entity class
|
|
9
|
+
* **the ORM registered**: a structurally identical copy read out of a package's
|
|
10
|
+
* source is a class the ORM never discovered, and `em.find` against it answers
|
|
11
|
+
* with nothing (D-160.6, D-160.6.1). A module package publishes one `entities`
|
|
12
|
+
* array and **no entity class by name** (D-168), so the class is picked out of
|
|
13
|
+
* that array by name — `@endora-commerce/test-kit/support`'s `entityNamedIn`,
|
|
14
|
+
* which is the lookup half and holds no population.
|
|
15
|
+
*
|
|
16
|
+
* The population is where this has to be a generated file. *Which modules one
|
|
17
|
+
* deployment installed* is the single fact a package that may name no module is
|
|
18
|
+
* forbidden to know (109 R2.2, FR-001), which is why
|
|
19
|
+
* `backend/test/helpers/package-entities.ts` is permanently host-owned and may
|
|
20
|
+
* neither move into a module package nor be published by the kit
|
|
21
|
+
* (`specs/084-small-f4-package-layout/contracts/module-package-layout.md` R10's
|
|
22
|
+
* closing paragraph — *"do not re-open this on volume"*). This file is the
|
|
23
|
+
* successor that paragraph names: the per-host artefact that gives a
|
|
24
|
+
* **stranger's** host the same index, derived from their install rather than
|
|
25
|
+
* from ours.
|
|
26
|
+
*
|
|
27
|
+
* ## One derivation, two populations
|
|
28
|
+
*
|
|
29
|
+
* `contracts/instance-repository.md` R3.5, exactly as `admin-artefacts.ts` is
|
|
30
|
+
* shared: `endora generate` renders it over the packages an instance installed,
|
|
31
|
+
* and `composer:generate` renders it over this repository's workspace members.
|
|
32
|
+
* A second implementation inside either host would be two answers to one
|
|
33
|
+
* question — and the one this repository holds would be the one nobody outside
|
|
34
|
+
* could correct.
|
|
35
|
+
*
|
|
36
|
+
* ## What it deliberately does not import, and the annotation that is not optional
|
|
37
|
+
*
|
|
38
|
+
* Nothing but the installed modules. A `satisfies InstalledEntityIndex` would
|
|
39
|
+
* read better and would put a type-only import of `@endora-commerce/test-kit`
|
|
40
|
+
* into a file **every** instance renders, including the overwhelming majority
|
|
41
|
+
* that run no test and never install the kit — an unresolvable specifier the
|
|
42
|
+
* first time such a client compiles the file. The shape is checked where it is
|
|
43
|
+
* used, at `entityNamedIn`'s argument position, by the consumer that needs it.
|
|
44
|
+
*
|
|
45
|
+
* The export is nevertheless **annotated**, with a type the file declares itself,
|
|
46
|
+
* and that is a measurement rather than a style: left inferred, `tsc` answers
|
|
47
|
+
* **TS2742** — *"the inferred type of `installedModuleEntities` cannot be named
|
|
48
|
+
* without a reference to `../node_modules/@endora-commerce/mod-…/dist/backend/
|
|
49
|
+
* entities/….entity`"* — once per entity class in the whole install, because the
|
|
50
|
+
* inferred type is a tuple of classes declared inside packages whose paths the
|
|
51
|
+
* consumer cannot name. The annotation is structurally the kit's
|
|
52
|
+
* `InstalledEntityIndex` and loses nothing a caller uses: `entityNamedIn` takes
|
|
53
|
+
* the module id as a **string**, so per-key precision has no reader.
|
|
54
|
+
*/
|
|
55
|
+
import { ModulePackageError } from './module-packages.js';
|
|
56
|
+
/**
|
|
57
|
+
* The subpath a module package publishes its composition root on, and the
|
|
58
|
+
* subpath the `entities` array comes off.
|
|
59
|
+
*
|
|
60
|
+
* Spelled rather than derived from the `exports` map's shape, because a module
|
|
61
|
+
* package's key set is **closed** (`module-package-layout.md` §2.2) and this is
|
|
62
|
+
* one of its keys: `MODULE_SUBPATH_MEANINGS` in
|
|
63
|
+
* `backend/scripts/lib/package-identity-files.ts` refuses a published subpath it
|
|
64
|
+
* has no meaning for, so `./backend` is a name and not a convention. Deriving it
|
|
65
|
+
* from a target directory's last segment — the shape the admin layer needs,
|
|
66
|
+
* because `./admin` is optional and a package may lay it out its own way — would
|
|
67
|
+
* be answering a question nobody is asking here.
|
|
68
|
+
*/
|
|
69
|
+
const BACKEND_SUBPATH = './backend';
|
|
70
|
+
/** The symbol the artefact exports, named once so every consumer agrees. */
|
|
71
|
+
export const ENTITY_INDEX_EXPORT = 'installedModuleEntities';
|
|
72
|
+
/**
|
|
73
|
+
* Every installed module package, sorted by module id.
|
|
74
|
+
*
|
|
75
|
+
* **A module that publishes no `./backend` is refused, not skipped.** A skip is
|
|
76
|
+
* how a whole module goes missing from an index without a word, and the failure
|
|
77
|
+
* then lands on whichever test asked for one of its entities — as
|
|
78
|
+
* `ModuleNotInstalledError` for a module the client did install, which sends
|
|
79
|
+
* them to look at their install instead of at the artefact. It is the same
|
|
80
|
+
* reason `collectAdminContributions` refuses a package whose admin layer no
|
|
81
|
+
* subpath covers.
|
|
82
|
+
*
|
|
83
|
+
* There is no *"has entities"* predicate and there deliberately cannot be one:
|
|
84
|
+
* whether the array is empty is a runtime fact about a package's JavaScript, and
|
|
85
|
+
* a generator that imported every installed module to find out would evaluate a
|
|
86
|
+
* client's whole backend to render a test artefact. Seven of this repository's
|
|
87
|
+
* own module packages publish an empty array, and an empty array in the index is
|
|
88
|
+
* the correct, loud answer — `entityNamed` names every class the array does
|
|
89
|
+
* declare, `(empty)` included.
|
|
90
|
+
*/
|
|
91
|
+
export function collectEntityIndexEntries(packages) {
|
|
92
|
+
const entries = [];
|
|
93
|
+
for (const pkg of packages) {
|
|
94
|
+
if (!pkg.exports.has(BACKEND_SUBPATH)) {
|
|
95
|
+
const declared = [...pkg.exports.keys()].sort().join(', ') || '(none)';
|
|
96
|
+
throw new ModulePackageError(`[composer] ${pkg.name} declares itself a module ('${pkg.moduleId}') and publishes no ` +
|
|
97
|
+
`'${BACKEND_SUBPATH}' subpath (declared: ${declared}). That subpath is the ` +
|
|
98
|
+
`composition root the platform calls and the one place a module's \`entities\` array ` +
|
|
99
|
+
`is reachable from, so the entity index cannot name this module's classes at all. ` +
|
|
100
|
+
`Leaving it out instead would report a module the client installed as one they did ` +
|
|
101
|
+
`not, which sends them to look at their install rather than at this artefact.`);
|
|
102
|
+
}
|
|
103
|
+
entries.push({
|
|
104
|
+
moduleId: pkg.moduleId,
|
|
105
|
+
specifier: `${pkg.name}/${BACKEND_SUBPATH.slice(2)}`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return [...entries].sort((a, b) => a.moduleId.localeCompare(b.moduleId));
|
|
109
|
+
}
|
|
110
|
+
/** Where the artefact lands, relative to the workspace root a host owns. */
|
|
111
|
+
export function entityIndexOutputPathIn(root) {
|
|
112
|
+
// The backend member, and **outside its `src`**: the member's own tsconfig
|
|
113
|
+
// sets `include: ['src']` with `rootDir: 'src'`, so a test artefact placed
|
|
114
|
+
// there would join the production build, and a `.ts` outside `rootDir` is
|
|
115
|
+
// TS6059 even for a type-only import. One path in both trees rather than one
|
|
116
|
+
// per tree — in this repository it lands beside the rest of `backend/test`'s
|
|
117
|
+
// own support files, which is where its only consumer already is.
|
|
118
|
+
return `${root}/backend/test/entities.generated.ts`;
|
|
119
|
+
}
|
|
120
|
+
/** A JS identifier for one entry's import binding — by position, never by id. */
|
|
121
|
+
function entityBindingOf(index) {
|
|
122
|
+
return `entities${index}`;
|
|
123
|
+
}
|
|
124
|
+
/** A module id as an object key: bare when it is an identifier, quoted otherwise. */
|
|
125
|
+
function keyOf(moduleId) {
|
|
126
|
+
return /^[A-Za-z$_][A-Za-z0-9$_]*$/.test(moduleId) ? moduleId : `'${moduleId}'`;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The "do not edit" header **this repository's own** generator writes, and the
|
|
130
|
+
* default for the same reason `emitAdminRegistry`'s is: an instance's own header
|
|
131
|
+
* says something different, and it passes it in.
|
|
132
|
+
*/
|
|
133
|
+
export const COMPOSER_ENTITY_INDEX_HEADER = `// AUTO-GENERATED by scripts/generate-composer.ts — DO NOT EDIT.\n` +
|
|
134
|
+
`// Run \`pnpm --filter backend run composer:generate\` to refresh. Editing this\n` +
|
|
135
|
+
`// file by hand is undone by the next run, and a stale index is a test asking\n` +
|
|
136
|
+
`// the ORM about a table nothing mapped.\n`;
|
|
137
|
+
/** Pure render of the entity index, exported so a test can drive it. */
|
|
138
|
+
export function emitEntityIndex(entries, header = COMPOSER_ENTITY_INDEX_HEADER) {
|
|
139
|
+
const imports = entries
|
|
140
|
+
.map((entry, index) => `import { entities as ${entityBindingOf(index)} } from '${entry.specifier}';`)
|
|
141
|
+
.join('\n');
|
|
142
|
+
const body = entries
|
|
143
|
+
.map((entry, index) => ` ${keyOf(entry.moduleId)}: ${entityBindingOf(index)},`)
|
|
144
|
+
.join('\n');
|
|
145
|
+
return `${header}//
|
|
146
|
+
// The entity index — every module **this host installed**, keyed by its module
|
|
147
|
+
// id, with the \`entities\` array that module published on its own \`./backend\`
|
|
148
|
+
// (\`specs/109-backend-test-kit/\` T065).
|
|
149
|
+
//
|
|
150
|
+
// ## What it is for
|
|
151
|
+
//
|
|
152
|
+
// A server-bound test writes rows, and a row needs the entity class **the ORM
|
|
153
|
+
// registered**. A module package publishes one \`entities\` array and no entity
|
|
154
|
+
// class by name (D-168), so a test picks the class out of the array:
|
|
155
|
+
//
|
|
156
|
+
// import { entityNamedIn } from '@endora-commerce/test-kit/support';
|
|
157
|
+
// import type { Widget as WidgetRow } from '@endora-commerce/mod-widgets/test-support';
|
|
158
|
+
// import { ${ENTITY_INDEX_EXPORT} } from './entities.generated.js';
|
|
159
|
+
//
|
|
160
|
+
// const Widget = entityNamedIn<WidgetRow>(${ENTITY_INDEX_EXPORT}, 'widgets', 'Widget');
|
|
161
|
+
//
|
|
162
|
+
// The **class** comes off the array, which is the one copy the ORM discovered;
|
|
163
|
+
// the **row type** comes off that module's \`./test-support\`, \`export type\` only,
|
|
164
|
+
// so nothing is evaluated twice (R10 property 3).
|
|
165
|
+
//
|
|
166
|
+
// ## Why it is generated and cannot be a package
|
|
167
|
+
//
|
|
168
|
+
// *Which modules one deployment installed* is the single fact a package that may
|
|
169
|
+
// name no module is forbidden to know (109 R2.2, FR-001). The kit therefore
|
|
170
|
+
// carries the lookup and the index's type and never a member of it, and this
|
|
171
|
+
// file — one per host, rendered from that host's own install — carries the
|
|
172
|
+
// population.
|
|
173
|
+
//
|
|
174
|
+
// **Resolution is by class name, never by position.** A tuple index compiles for
|
|
175
|
+
// any ordering, so re-ordering the array inside a module would silently re-point
|
|
176
|
+
// every caller at another table.
|
|
177
|
+
|
|
178
|
+
${imports}${imports === '' ? '' : '\n'}
|
|
179
|
+
/**
|
|
180
|
+
* What a module package publishes in its \`entities\` array.
|
|
181
|
+
*
|
|
182
|
+
* Declared here rather than imported from the kit, so this file has no
|
|
183
|
+
* dependency of its own — an instance that runs no test never installs the kit,
|
|
184
|
+
* and a type-only import of it would be unresolvable the first time such a client
|
|
185
|
+
* compiled this file. It is structurally \`InstalledEntityIndex\`, which is what
|
|
186
|
+
* the consumer's argument position checks it against.
|
|
187
|
+
*/
|
|
188
|
+
type PublishedEntityClass = abstract new (...args: never[]) => object;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Every installed module's published entity classes, keyed by module id.
|
|
192
|
+
*
|
|
193
|
+
* **Annotated, not inferred**, and that is TS2742 rather than a preference: the
|
|
194
|
+
* inferred type is a tuple of classes declared inside packages whose paths a
|
|
195
|
+
* consumer cannot name, so \`tsc\` refuses it once per entity class in the whole
|
|
196
|
+
* install. Nothing a caller uses is lost — \`entityNamedIn\` takes the module id as
|
|
197
|
+
* a string.
|
|
198
|
+
*
|
|
199
|
+
* A module with an empty array is a module that owns no table, which is a legal
|
|
200
|
+
* state with a loud answer: asking for a class of it names every class it does
|
|
201
|
+
* declare, \`(empty)\` included. A module that is **absent** is a different
|
|
202
|
+
* answer — \`ModuleNotInstalledError\`, naming the ids that are here.
|
|
203
|
+
*/
|
|
204
|
+
export const ${ENTITY_INDEX_EXPORT}: Readonly<
|
|
205
|
+
Record<string, readonly PublishedEntityClass[]>
|
|
206
|
+
> = {
|
|
207
|
+
${body}${body === '' ? '' : '\n'}};
|
|
208
|
+
`;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=entity-index-artefact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-index-artefact.js","sourceRoot":"","sources":["../../src/lib/entity-index-artefact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-instance build inputs — the values that genuinely vary between one
|
|
3
|
+
* deployment of this platform and another, and that nothing derives
|
|
4
|
+
* (`specs/110-instance-repository/` FR-009).
|
|
5
|
+
*
|
|
6
|
+
* ## Why this file exists
|
|
7
|
+
*
|
|
8
|
+
* They are an **instance's**, not our pipeline's. Under D-207 a client's
|
|
9
|
+
* repository depends on the platform, the admin shell and the module packages
|
|
10
|
+
* and holds a copy of none of them, so everything a build needs is either
|
|
11
|
+
* derived by the platform or is one of these; and `spec.md` §5 is the argument
|
|
12
|
+
* against the *kind* of input that does not belong here — five of
|
|
13
|
+
* `endora.config.ts`'s six fields restate a fact something already derives,
|
|
14
|
+
* which is D-100 at the scale of a whole file in a tree we cannot grep.
|
|
15
|
+
*
|
|
16
|
+
* **§5 was written down as "there is no fifth", and a fifth arrived.**
|
|
17
|
+
* `STOREFRONT_DOMAIN` was already a required CI/CD variable, classified in
|
|
18
|
+
* `.gitlab-ci.yml` as a domain the pipeline *deploys to* rather than one a build
|
|
19
|
+
* reads — correct until the storefront had to name its own public origin inside
|
|
20
|
+
* a bundle. Nothing derives it, and the storefront's canonicals, its sitemap and
|
|
21
|
+
* its robots.txt are all built from it. So the closed set was a count of a
|
|
22
|
+
* derived fact written into prose (D-100); what survives the correction is §5's
|
|
23
|
+
* actual test — *does something already derive this?* — which is a predicate and
|
|
24
|
+
* not a number.
|
|
25
|
+
*
|
|
26
|
+
* Before this declaration existed, the set was written in three places in
|
|
27
|
+
* `.gitlab-ci.yml` and nowhere else: a comment block listing the CI/CD
|
|
28
|
+
* variables an operator must set, and two `docker build` invocations spelling
|
|
29
|
+
* the mapping from an input to the build argument each image reads. Nothing
|
|
30
|
+
* reconciled the three, nothing could tell a client which values they owe, and
|
|
31
|
+
* **`DEPLOYMENT` reached no build at all** — the one input whose absence is
|
|
32
|
+
* silent, because `selectedDeployment` reads a blank value as *bare core* and a
|
|
33
|
+
* deployment whose overlay modules simply did not compose looks exactly like a
|
|
34
|
+
* deployment that has none.
|
|
35
|
+
*
|
|
36
|
+
* ## What is here, and what is deliberately not
|
|
37
|
+
*
|
|
38
|
+
* Each input carries its **meaning**, an **example**, and its **default** —
|
|
39
|
+
* `null` where the instance must supply one, because a value the tool invented
|
|
40
|
+
* is a value nobody reviewed (`cli-product.md` R2.5). Each also carries its
|
|
41
|
+
* consumers: which build reads it, under which name, and how the value is
|
|
42
|
+
* spelled.
|
|
43
|
+
*
|
|
44
|
+
* The spelling is a **shell expansion** over the input names (`https://${API_DOMAIN}`)
|
|
45
|
+
* for one reason: it is the form a pipeline can paste verbatim and the form a
|
|
46
|
+
* renderer can substitute into, so the mapping has one home rather than one per
|
|
47
|
+
* consumer. Nothing here knows what a GitLab job is; `.gitlab-ci.yml` reads
|
|
48
|
+
* this list, `endora new instance` will render an `.env` and a pipeline from it
|
|
49
|
+
* (T132), and `backend/test/unit/ci/instance-build-inputs.test.ts` is what
|
|
50
|
+
* refuses a third spelling.
|
|
51
|
+
*/
|
|
52
|
+
/** Which build reads an input. The storefront is scaffolded separately (D-195). */
|
|
53
|
+
export type BuildTarget = 'backend' | 'admin' | 'storefront';
|
|
54
|
+
/** One build's use of one input. */
|
|
55
|
+
export interface BuildInputConsumer {
|
|
56
|
+
readonly target: BuildTarget;
|
|
57
|
+
/** The `ARG` the image declares, and the `--build-arg` a pipeline passes. */
|
|
58
|
+
readonly buildArg: string;
|
|
59
|
+
/**
|
|
60
|
+
* The value, written as a shell expansion over the input names.
|
|
61
|
+
*
|
|
62
|
+
* `${API_DOMAIN}` rather than `$API_DOMAIN`: both expand, and the braced form
|
|
63
|
+
* is the one that cannot silently swallow a following character.
|
|
64
|
+
*/
|
|
65
|
+
readonly value: string;
|
|
66
|
+
}
|
|
67
|
+
/** One per-instance build input. */
|
|
68
|
+
export interface InstanceBuildInput {
|
|
69
|
+
/** The environment variable an operator sets, and the name a value expands to. */
|
|
70
|
+
readonly name: string;
|
|
71
|
+
/** What it decides. One sentence, for a client's developer reading it first. */
|
|
72
|
+
readonly meaning: string;
|
|
73
|
+
readonly example: string;
|
|
74
|
+
/**
|
|
75
|
+
* The value used when the instance sets none, or `null` when it must set one.
|
|
76
|
+
*
|
|
77
|
+
* A `null` default is not an omission: it says the platform has no honest
|
|
78
|
+
* answer, and the refusal belongs to whatever reads it.
|
|
79
|
+
*/
|
|
80
|
+
readonly default: string | null;
|
|
81
|
+
readonly consumers: readonly BuildInputConsumer[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* They are declared in the order a client meets them.
|
|
85
|
+
*
|
|
86
|
+
* `DEPLOYMENT` first because it is the one an instance always has — it names
|
|
87
|
+
* the client's own deployment directory, where their overlay modules and their
|
|
88
|
+
* `divergence.ts` live (Principle XV) — and the rest are what the two frontend
|
|
89
|
+
* builds inline into their bundles.
|
|
90
|
+
*/
|
|
91
|
+
export declare const INSTANCE_BUILD_INPUTS: readonly InstanceBuildInput[];
|
|
92
|
+
/** Every consumer of one build target, in declaration order. */
|
|
93
|
+
export declare function buildInputsFor(target: BuildTarget, inputs?: readonly InstanceBuildInput[]): readonly {
|
|
94
|
+
readonly input: InstanceBuildInput;
|
|
95
|
+
readonly consumer: BuildInputConsumer;
|
|
96
|
+
}[];
|
|
97
|
+
/**
|
|
98
|
+
* The `--build-arg` flags one image build takes, one per line.
|
|
99
|
+
*
|
|
100
|
+
* Emitted rather than written down, so a pipeline — ours or a client's — passes
|
|
101
|
+
* what the declaration says and cannot come to pass a fourth spelling of it.
|
|
102
|
+
*
|
|
103
|
+
* A default is applied **here**, as POSIX's own `${NAME:-value}` expansion,
|
|
104
|
+
* rather than being repeated inside every template that mentions the input:
|
|
105
|
+
* the default has one home, and a reader of the emitted flag can see it.
|
|
106
|
+
*/
|
|
107
|
+
export declare function buildArgFlags(target: BuildTarget, inputs?: readonly InstanceBuildInput[]): readonly string[];
|
|
108
|
+
//# sourceMappingURL=instance-build-inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-build-inputs.d.ts","sourceRoot":"","sources":["../../src/lib/instance-build-inputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,mFAAmF;AACnF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;AAE7D,oCAAoC;AACpC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,oCAAoC;AACpC,MAAM,WAAW,kBAAkB;IACjC,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACnD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,kBAAkB,EAkF9D,CAAC;AAEF,gEAAgE;AAChE,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,MAAM,GAAE,SAAS,kBAAkB,EAA0B,GAC5D,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAA;CAAE,EAAE,CAM1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,WAAW,EACnB,MAAM,GAAE,SAAS,kBAAkB,EAA0B,GAC5D,SAAS,MAAM,EAAE,CAWnB"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-instance build inputs — the values that genuinely vary between one
|
|
3
|
+
* deployment of this platform and another, and that nothing derives
|
|
4
|
+
* (`specs/110-instance-repository/` FR-009).
|
|
5
|
+
*
|
|
6
|
+
* ## Why this file exists
|
|
7
|
+
*
|
|
8
|
+
* They are an **instance's**, not our pipeline's. Under D-207 a client's
|
|
9
|
+
* repository depends on the platform, the admin shell and the module packages
|
|
10
|
+
* and holds a copy of none of them, so everything a build needs is either
|
|
11
|
+
* derived by the platform or is one of these; and `spec.md` §5 is the argument
|
|
12
|
+
* against the *kind* of input that does not belong here — five of
|
|
13
|
+
* `endora.config.ts`'s six fields restate a fact something already derives,
|
|
14
|
+
* which is D-100 at the scale of a whole file in a tree we cannot grep.
|
|
15
|
+
*
|
|
16
|
+
* **§5 was written down as "there is no fifth", and a fifth arrived.**
|
|
17
|
+
* `STOREFRONT_DOMAIN` was already a required CI/CD variable, classified in
|
|
18
|
+
* `.gitlab-ci.yml` as a domain the pipeline *deploys to* rather than one a build
|
|
19
|
+
* reads — correct until the storefront had to name its own public origin inside
|
|
20
|
+
* a bundle. Nothing derives it, and the storefront's canonicals, its sitemap and
|
|
21
|
+
* its robots.txt are all built from it. So the closed set was a count of a
|
|
22
|
+
* derived fact written into prose (D-100); what survives the correction is §5's
|
|
23
|
+
* actual test — *does something already derive this?* — which is a predicate and
|
|
24
|
+
* not a number.
|
|
25
|
+
*
|
|
26
|
+
* Before this declaration existed, the set was written in three places in
|
|
27
|
+
* `.gitlab-ci.yml` and nowhere else: a comment block listing the CI/CD
|
|
28
|
+
* variables an operator must set, and two `docker build` invocations spelling
|
|
29
|
+
* the mapping from an input to the build argument each image reads. Nothing
|
|
30
|
+
* reconciled the three, nothing could tell a client which values they owe, and
|
|
31
|
+
* **`DEPLOYMENT` reached no build at all** — the one input whose absence is
|
|
32
|
+
* silent, because `selectedDeployment` reads a blank value as *bare core* and a
|
|
33
|
+
* deployment whose overlay modules simply did not compose looks exactly like a
|
|
34
|
+
* deployment that has none.
|
|
35
|
+
*
|
|
36
|
+
* ## What is here, and what is deliberately not
|
|
37
|
+
*
|
|
38
|
+
* Each input carries its **meaning**, an **example**, and its **default** —
|
|
39
|
+
* `null` where the instance must supply one, because a value the tool invented
|
|
40
|
+
* is a value nobody reviewed (`cli-product.md` R2.5). Each also carries its
|
|
41
|
+
* consumers: which build reads it, under which name, and how the value is
|
|
42
|
+
* spelled.
|
|
43
|
+
*
|
|
44
|
+
* The spelling is a **shell expansion** over the input names (`https://${API_DOMAIN}`)
|
|
45
|
+
* for one reason: it is the form a pipeline can paste verbatim and the form a
|
|
46
|
+
* renderer can substitute into, so the mapping has one home rather than one per
|
|
47
|
+
* consumer. Nothing here knows what a GitLab job is; `.gitlab-ci.yml` reads
|
|
48
|
+
* this list, `endora new instance` will render an `.env` and a pipeline from it
|
|
49
|
+
* (T132), and `backend/test/unit/ci/instance-build-inputs.test.ts` is what
|
|
50
|
+
* refuses a third spelling.
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* They are declared in the order a client meets them.
|
|
54
|
+
*
|
|
55
|
+
* `DEPLOYMENT` first because it is the one an instance always has — it names
|
|
56
|
+
* the client's own deployment directory, where their overlay modules and their
|
|
57
|
+
* `divergence.ts` live (Principle XV) — and the rest are what the two frontend
|
|
58
|
+
* builds inline into their bundles.
|
|
59
|
+
*/
|
|
60
|
+
export const INSTANCE_BUILD_INPUTS = [
|
|
61
|
+
{
|
|
62
|
+
name: 'DEPLOYMENT',
|
|
63
|
+
meaning: "The deployment whose overlay modules and divergence declaration this build composes. " +
|
|
64
|
+
'Unset, or blank, is bare core: no overlay module is composed and the build behaves ' +
|
|
65
|
+
'byte-for-byte like one with no deployment directory at all.',
|
|
66
|
+
example: 'acme',
|
|
67
|
+
// A platform with no deployment is a real and supported state — it is what
|
|
68
|
+
// `test:backend`'s bare-core shards run — so "none" is a default rather
|
|
69
|
+
// than a missing value.
|
|
70
|
+
default: null,
|
|
71
|
+
consumers: [{ target: 'backend', buildArg: 'DEPLOYMENT', value: '${DEPLOYMENT}' }],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'API_DOMAIN',
|
|
75
|
+
meaning: 'The host the instance serves its API from. Both frontends inline it at build time, ' +
|
|
76
|
+
'because a bundle cannot resolve it later.',
|
|
77
|
+
example: 'api.example.com',
|
|
78
|
+
default: null,
|
|
79
|
+
consumers: [
|
|
80
|
+
{ target: 'admin', buildArg: 'VITE_API_BASE_URL', value: 'https://${API_DOMAIN}' },
|
|
81
|
+
{
|
|
82
|
+
target: 'storefront',
|
|
83
|
+
buildArg: 'NEXT_PUBLIC_API_BASE_URL',
|
|
84
|
+
value: 'https://${API_DOMAIN}',
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'STOREFRONT_DOMAIN',
|
|
90
|
+
// It was already a required CI/CD variable and was classified as a domain
|
|
91
|
+
// this pipeline *deploys to* rather than a build input — true until the
|
|
92
|
+
// storefront had to name its own origin in a bundle. `endora new storefront`
|
|
93
|
+
// asks for the same fact as `NEXT_PUBLIC_SITE_URL`, and the backend's
|
|
94
|
+
// `STOREFRONT_BASE_URL` is built from this variable in
|
|
95
|
+
// `deploy/compose.prod.yml`, so this is one fact reaching a third reader.
|
|
96
|
+
meaning: 'The host the instance serves its storefront from. The storefront inlines it at build ' +
|
|
97
|
+
'time as the origin it puts in every canonical link, in its sitemap and in its ' +
|
|
98
|
+
'robots.txt — none of which a running container can correct afterwards.',
|
|
99
|
+
example: 'example.com',
|
|
100
|
+
default: null,
|
|
101
|
+
consumers: [
|
|
102
|
+
{
|
|
103
|
+
target: 'storefront',
|
|
104
|
+
buildArg: 'NEXT_PUBLIC_SITE_URL',
|
|
105
|
+
value: 'https://${STOREFRONT_DOMAIN}',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'SALES_CHANNEL_CODE',
|
|
111
|
+
meaning: 'The sales channel the storefront resolves its content against (Principle XII). One ' +
|
|
112
|
+
'always exists — the install creates it — so this names which, never whether.',
|
|
113
|
+
example: 'pl_default',
|
|
114
|
+
default: null,
|
|
115
|
+
consumers: [
|
|
116
|
+
{
|
|
117
|
+
target: 'storefront',
|
|
118
|
+
buildArg: 'NEXT_PUBLIC_SALES_CHANNEL_CODE',
|
|
119
|
+
value: '${SALES_CHANNEL_CODE}',
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'DEFAULT_LOCALE',
|
|
125
|
+
meaning: "The locale the storefront renders when the reader asks for none. A message missing " +
|
|
126
|
+
'from it falls back to English, which is the platform default every module ships.',
|
|
127
|
+
example: 'en-US',
|
|
128
|
+
default: 'en-US',
|
|
129
|
+
consumers: [
|
|
130
|
+
{
|
|
131
|
+
target: 'storefront',
|
|
132
|
+
buildArg: 'NEXT_PUBLIC_DEFAULT_LOCALE',
|
|
133
|
+
value: '${DEFAULT_LOCALE}',
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
/** Every consumer of one build target, in declaration order. */
|
|
139
|
+
export function buildInputsFor(target, inputs = INSTANCE_BUILD_INPUTS) {
|
|
140
|
+
return inputs.flatMap((input) => input.consumers
|
|
141
|
+
.filter((consumer) => consumer.target === target)
|
|
142
|
+
.map((consumer) => ({ input, consumer })));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The `--build-arg` flags one image build takes, one per line.
|
|
146
|
+
*
|
|
147
|
+
* Emitted rather than written down, so a pipeline — ours or a client's — passes
|
|
148
|
+
* what the declaration says and cannot come to pass a fourth spelling of it.
|
|
149
|
+
*
|
|
150
|
+
* A default is applied **here**, as POSIX's own `${NAME:-value}` expansion,
|
|
151
|
+
* rather than being repeated inside every template that mentions the input:
|
|
152
|
+
* the default has one home, and a reader of the emitted flag can see it.
|
|
153
|
+
*/
|
|
154
|
+
export function buildArgFlags(target, inputs = INSTANCE_BUILD_INPUTS) {
|
|
155
|
+
const defaults = new Map(inputs
|
|
156
|
+
.filter((input) => input.default !== null)
|
|
157
|
+
.map((input) => [`\${${input.name}}`, `\${${input.name}:-${input.default}}`]));
|
|
158
|
+
return buildInputsFor(target, inputs).map(({ consumer }) => {
|
|
159
|
+
let value = consumer.value;
|
|
160
|
+
for (const [plain, withDefault] of defaults)
|
|
161
|
+
value = value.split(plain).join(withDefault);
|
|
162
|
+
return `--build-arg ${consumer.buildArg}="${value}"`;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=instance-build-inputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-build-inputs.js","sourceRoot":"","sources":["../../src/lib/instance-build-inputs.ts"],"names":[],"mappings":"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"}
|