@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.
Files changed (356) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/bin/endora.d.ts +28 -0
  4. package/dist/bin/endora.d.ts.map +1 -0
  5. package/dist/bin/endora.js +926 -0
  6. package/dist/bin/endora.js.map +1 -0
  7. package/dist/check/estate.d.ts +189 -0
  8. package/dist/check/estate.d.ts.map +1 -0
  9. package/dist/check/estate.js +1037 -0
  10. package/dist/check/estate.js.map +1 -0
  11. package/dist/check/hosts.d.ts +25 -0
  12. package/dist/check/hosts.d.ts.map +1 -0
  13. package/dist/check/hosts.js +1347 -0
  14. package/dist/check/hosts.js.map +1 -0
  15. package/dist/check/index.d.ts +60 -0
  16. package/dist/check/index.d.ts.map +1 -0
  17. package/dist/check/index.js +111 -0
  18. package/dist/check/index.js.map +1 -0
  19. package/dist/check/layout.d.ts +136 -0
  20. package/dist/check/layout.d.ts.map +1 -0
  21. package/dist/check/layout.js +262 -0
  22. package/dist/check/layout.js.map +1 -0
  23. package/dist/check/ledger.d.ts +98 -0
  24. package/dist/check/ledger.d.ts.map +1 -0
  25. package/dist/check/ledger.js +173 -0
  26. package/dist/check/ledger.js.map +1 -0
  27. package/dist/check/peer-owners.d.ts +116 -0
  28. package/dist/check/peer-owners.d.ts.map +1 -0
  29. package/dist/check/peer-owners.js +225 -0
  30. package/dist/check/peer-owners.js.map +1 -0
  31. package/dist/check/report.d.ts +33 -0
  32. package/dist/check/report.d.ts.map +1 -0
  33. package/dist/check/report.js +107 -0
  34. package/dist/check/report.js.map +1 -0
  35. package/dist/check/run.d.ts +147 -0
  36. package/dist/check/run.d.ts.map +1 -0
  37. package/dist/check/run.js +111 -0
  38. package/dist/check/run.js.map +1 -0
  39. package/dist/checks.d.ts +17 -0
  40. package/dist/checks.d.ts.map +1 -0
  41. package/dist/checks.js +17 -0
  42. package/dist/checks.js.map +1 -0
  43. package/dist/dev/index.d.ts +83 -0
  44. package/dist/dev/index.d.ts.map +1 -0
  45. package/dist/dev/index.js +298 -0
  46. package/dist/dev/index.js.map +1 -0
  47. package/dist/generate/divergence.d.ts +38 -0
  48. package/dist/generate/divergence.d.ts.map +1 -0
  49. package/dist/generate/divergence.js +237 -0
  50. package/dist/generate/divergence.js.map +1 -0
  51. package/dist/generate/index.d.ts +90 -0
  52. package/dist/generate/index.d.ts.map +1 -0
  53. package/dist/generate/index.js +369 -0
  54. package/dist/generate/index.js.map +1 -0
  55. package/dist/index.d.ts +23 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +35 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/inputs/declaration.d.ts +18 -0
  60. package/dist/inputs/declaration.d.ts.map +1 -0
  61. package/dist/inputs/declaration.js +64 -0
  62. package/dist/inputs/declaration.js.map +1 -0
  63. package/dist/inputs/env-file.d.ts +73 -0
  64. package/dist/inputs/env-file.d.ts.map +1 -0
  65. package/dist/inputs/env-file.js +134 -0
  66. package/dist/inputs/env-file.js.map +1 -0
  67. package/dist/inputs/prompt.d.ts +21 -0
  68. package/dist/inputs/prompt.d.ts.map +1 -0
  69. package/dist/inputs/prompt.js +59 -0
  70. package/dist/inputs/prompt.js.map +1 -0
  71. package/dist/inputs/resolve.d.ts +163 -0
  72. package/dist/inputs/resolve.d.ts.map +1 -0
  73. package/dist/inputs/resolve.js +290 -0
  74. package/dist/inputs/resolve.js.map +1 -0
  75. package/dist/install/host.d.ts +27 -0
  76. package/dist/install/host.d.ts.map +1 -0
  77. package/dist/install/host.js +90 -0
  78. package/dist/install/host.js.map +1 -0
  79. package/dist/install/index.d.ts +173 -0
  80. package/dist/install/index.d.ts.map +1 -0
  81. package/dist/install/index.js +793 -0
  82. package/dist/install/index.js.map +1 -0
  83. package/dist/install/wizard.d.ts +144 -0
  84. package/dist/install/wizard.d.ts.map +1 -0
  85. package/dist/install/wizard.js +362 -0
  86. package/dist/install/wizard.js.map +1 -0
  87. package/dist/lib/admin-artefacts.d.ts +70 -0
  88. package/dist/lib/admin-artefacts.d.ts.map +1 -0
  89. package/dist/lib/admin-artefacts.js +354 -0
  90. package/dist/lib/admin-artefacts.js.map +1 -0
  91. package/dist/lib/admin-surfaces.d.ts +298 -0
  92. package/dist/lib/admin-surfaces.d.ts.map +1 -0
  93. package/dist/lib/admin-surfaces.js +669 -0
  94. package/dist/lib/admin-surfaces.js.map +1 -0
  95. package/dist/lib/delegated-composer.d.ts +85 -0
  96. package/dist/lib/delegated-composer.d.ts.map +1 -0
  97. package/dist/lib/delegated-composer.js +241 -0
  98. package/dist/lib/delegated-composer.js.map +1 -0
  99. package/dist/lib/divergence-artefacts.d.ts +305 -0
  100. package/dist/lib/divergence-artefacts.d.ts.map +1 -0
  101. package/dist/lib/divergence-artefacts.js +828 -0
  102. package/dist/lib/divergence-artefacts.js.map +1 -0
  103. package/dist/lib/divergence.d.ts +337 -0
  104. package/dist/lib/divergence.d.ts.map +1 -0
  105. package/dist/lib/divergence.js +1005 -0
  106. package/dist/lib/divergence.js.map +1 -0
  107. package/dist/lib/docs-artefacts.d.ts +395 -0
  108. package/dist/lib/docs-artefacts.d.ts.map +1 -0
  109. package/dist/lib/docs-artefacts.js +781 -0
  110. package/dist/lib/docs-artefacts.js.map +1 -0
  111. package/dist/lib/emitted-exports.d.ts +21 -0
  112. package/dist/lib/emitted-exports.d.ts.map +1 -0
  113. package/dist/lib/emitted-exports.js +96 -0
  114. package/dist/lib/emitted-exports.js.map +1 -0
  115. package/dist/lib/emitted-freshness.d.ts +112 -0
  116. package/dist/lib/emitted-freshness.d.ts.map +1 -0
  117. package/dist/lib/emitted-freshness.js +288 -0
  118. package/dist/lib/emitted-freshness.js.map +1 -0
  119. package/dist/lib/entity-index-artefact.d.ts +95 -0
  120. package/dist/lib/entity-index-artefact.d.ts.map +1 -0
  121. package/dist/lib/entity-index-artefact.js +210 -0
  122. package/dist/lib/entity-index-artefact.js.map +1 -0
  123. package/dist/lib/instance-build-inputs.d.ts +108 -0
  124. package/dist/lib/instance-build-inputs.d.ts.map +1 -0
  125. package/dist/lib/instance-build-inputs.js +165 -0
  126. package/dist/lib/instance-build-inputs.js.map +1 -0
  127. package/dist/lib/module-docs.d.ts +473 -0
  128. package/dist/lib/module-docs.d.ts.map +1 -0
  129. package/dist/lib/module-docs.js +711 -0
  130. package/dist/lib/module-docs.js.map +1 -0
  131. package/dist/lib/module-package-subpaths.d.ts +56 -0
  132. package/dist/lib/module-package-subpaths.d.ts.map +1 -0
  133. package/dist/lib/module-package-subpaths.js +223 -0
  134. package/dist/lib/module-package-subpaths.js.map +1 -0
  135. package/dist/lib/module-packages.d.ts +200 -0
  136. package/dist/lib/module-packages.d.ts.map +1 -0
  137. package/dist/lib/module-packages.js +580 -0
  138. package/dist/lib/module-packages.js.map +1 -0
  139. package/dist/lib/module-population.d.ts +129 -0
  140. package/dist/lib/module-population.d.ts.map +1 -0
  141. package/dist/lib/module-population.js +172 -0
  142. package/dist/lib/module-population.js.map +1 -0
  143. package/dist/lib/module-roots.d.ts +337 -0
  144. package/dist/lib/module-roots.d.ts.map +1 -0
  145. package/dist/lib/module-roots.js +586 -0
  146. package/dist/lib/module-roots.js.map +1 -0
  147. package/dist/lib/nested-checkouts.d.ts +33 -0
  148. package/dist/lib/nested-checkouts.d.ts.map +1 -0
  149. package/dist/lib/nested-checkouts.js +160 -0
  150. package/dist/lib/nested-checkouts.js.map +1 -0
  151. package/dist/lib/platform-root.d.ts +43 -0
  152. package/dist/lib/platform-root.d.ts.map +1 -0
  153. package/dist/lib/platform-root.js +134 -0
  154. package/dist/lib/platform-root.js.map +1 -0
  155. package/dist/lib/platform-surface.d.ts +235 -0
  156. package/dist/lib/platform-surface.d.ts.map +1 -0
  157. package/dist/lib/platform-surface.js +393 -0
  158. package/dist/lib/platform-surface.js.map +1 -0
  159. package/dist/lib/port-registrations.d.ts +223 -0
  160. package/dist/lib/port-registrations.d.ts.map +1 -0
  161. package/dist/lib/port-registrations.js +532 -0
  162. package/dist/lib/port-registrations.js.map +1 -0
  163. package/dist/lib/read-size.d.ts +154 -0
  164. package/dist/lib/read-size.d.ts.map +1 -0
  165. package/dist/lib/read-size.js +182 -0
  166. package/dist/lib/read-size.js.map +1 -0
  167. package/dist/lib/registration-owners.d.ts +79 -0
  168. package/dist/lib/registration-owners.d.ts.map +1 -0
  169. package/dist/lib/registration-owners.js +77 -0
  170. package/dist/lib/registration-owners.js.map +1 -0
  171. package/dist/lib/release-index.d.ts +53 -0
  172. package/dist/lib/release-index.d.ts.map +1 -0
  173. package/dist/lib/release-index.js +162 -0
  174. package/dist/lib/release-index.js.map +1 -0
  175. package/dist/lib/repeating-timers.d.ts +79 -0
  176. package/dist/lib/repeating-timers.d.ts.map +1 -0
  177. package/dist/lib/repeating-timers.js +189 -0
  178. package/dist/lib/repeating-timers.js.map +1 -0
  179. package/dist/lib/source-text.d.ts +34 -0
  180. package/dist/lib/source-text.d.ts.map +1 -0
  181. package/dist/lib/source-text.js +80 -0
  182. package/dist/lib/source-text.js.map +1 -0
  183. package/dist/lib/specifiers.d.ts +20 -0
  184. package/dist/lib/specifiers.d.ts.map +1 -0
  185. package/dist/lib/specifiers.js +130 -0
  186. package/dist/lib/specifiers.js.map +1 -0
  187. package/dist/lib/sql-tables.d.ts +166 -0
  188. package/dist/lib/sql-tables.d.ts.map +1 -0
  189. package/dist/lib/sql-tables.js +464 -0
  190. package/dist/lib/sql-tables.js.map +1 -0
  191. package/dist/lib/switchable-modules.d.ts +54 -0
  192. package/dist/lib/switchable-modules.d.ts.map +1 -0
  193. package/dist/lib/switchable-modules.js +104 -0
  194. package/dist/lib/switchable-modules.js.map +1 -0
  195. package/dist/lib/tailwind-sources.d.ts +136 -0
  196. package/dist/lib/tailwind-sources.d.ts.map +1 -0
  197. package/dist/lib/tailwind-sources.js +307 -0
  198. package/dist/lib/tailwind-sources.js.map +1 -0
  199. package/dist/lib/ui-layer.d.ts +54 -0
  200. package/dist/lib/ui-layer.d.ts.map +1 -0
  201. package/dist/lib/ui-layer.js +57 -0
  202. package/dist/lib/ui-layer.js.map +1 -0
  203. package/dist/lib/workspace-packages.d.ts +186 -0
  204. package/dist/lib/workspace-packages.d.ts.map +1 -0
  205. package/dist/lib/workspace-packages.js +351 -0
  206. package/dist/lib/workspace-packages.js.map +1 -0
  207. package/dist/new-instance/deploy.d.ts +211 -0
  208. package/dist/new-instance/deploy.d.ts.map +1 -0
  209. package/dist/new-instance/deploy.js +1381 -0
  210. package/dist/new-instance/deploy.js.map +1 -0
  211. package/dist/new-instance/docs-toolchain.d.ts +66 -0
  212. package/dist/new-instance/docs-toolchain.d.ts.map +1 -0
  213. package/dist/new-instance/docs-toolchain.js +69 -0
  214. package/dist/new-instance/docs-toolchain.js.map +1 -0
  215. package/dist/new-instance/host.d.ts +124 -0
  216. package/dist/new-instance/host.d.ts.map +1 -0
  217. package/dist/new-instance/host.js +276 -0
  218. package/dist/new-instance/host.js.map +1 -0
  219. package/dist/new-instance/index.d.ts +118 -0
  220. package/dist/new-instance/index.d.ts.map +1 -0
  221. package/dist/new-instance/index.js +567 -0
  222. package/dist/new-instance/index.js.map +1 -0
  223. package/dist/new-instance/modules.d.ts +188 -0
  224. package/dist/new-instance/modules.d.ts.map +1 -0
  225. package/dist/new-instance/modules.js +392 -0
  226. package/dist/new-instance/modules.js.map +1 -0
  227. package/dist/new-instance/template.d.ts +505 -0
  228. package/dist/new-instance/template.d.ts.map +1 -0
  229. package/dist/new-instance/template.js +1886 -0
  230. package/dist/new-instance/template.js.map +1 -0
  231. package/dist/new-module/emit.d.ts +67 -0
  232. package/dist/new-module/emit.d.ts.map +1 -0
  233. package/dist/new-module/emit.js +1393 -0
  234. package/dist/new-module/emit.js.map +1 -0
  235. package/dist/new-module/host.d.ts +67 -0
  236. package/dist/new-module/host.d.ts.map +1 -0
  237. package/dist/new-module/host.js +224 -0
  238. package/dist/new-module/host.js.map +1 -0
  239. package/dist/new-module/index.d.ts +32 -0
  240. package/dist/new-module/index.d.ts.map +1 -0
  241. package/dist/new-module/index.js +193 -0
  242. package/dist/new-module/index.js.map +1 -0
  243. package/dist/new-module/spec.d.ts +188 -0
  244. package/dist/new-module/spec.d.ts.map +1 -0
  245. package/dist/new-module/spec.js +404 -0
  246. package/dist/new-module/spec.js.map +1 -0
  247. package/dist/new-module/text.d.ts +15 -0
  248. package/dist/new-module/text.d.ts.map +1 -0
  249. package/dist/new-module/text.js +22 -0
  250. package/dist/new-module/text.js.map +1 -0
  251. package/dist/new-storefront/dockerfile.d.ts +20 -0
  252. package/dist/new-storefront/dockerfile.d.ts.map +1 -0
  253. package/dist/new-storefront/dockerfile.js +131 -0
  254. package/dist/new-storefront/dockerfile.js.map +1 -0
  255. package/dist/new-storefront/gitignore.d.ts +23 -0
  256. package/dist/new-storefront/gitignore.d.ts.map +1 -0
  257. package/dist/new-storefront/gitignore.js +39 -0
  258. package/dist/new-storefront/gitignore.js.map +1 -0
  259. package/dist/new-storefront/index.d.ts +93 -0
  260. package/dist/new-storefront/index.d.ts.map +1 -0
  261. package/dist/new-storefront/index.js +329 -0
  262. package/dist/new-storefront/index.js.map +1 -0
  263. package/dist/new-storefront/npmrc.d.ts +98 -0
  264. package/dist/new-storefront/npmrc.d.ts.map +1 -0
  265. package/dist/new-storefront/npmrc.js +217 -0
  266. package/dist/new-storefront/npmrc.js.map +1 -0
  267. package/dist/new-storefront/reference.d.ts +189 -0
  268. package/dist/new-storefront/reference.d.ts.map +1 -0
  269. package/dist/new-storefront/reference.js +430 -0
  270. package/dist/new-storefront/reference.js.map +1 -0
  271. package/dist/new-storefront/rewrite.d.ts +171 -0
  272. package/dist/new-storefront/rewrite.d.ts.map +1 -0
  273. package/dist/new-storefront/rewrite.js +701 -0
  274. package/dist/new-storefront/rewrite.js.map +1 -0
  275. package/dist/release-index.json +284 -0
  276. package/dist/rules/action-route-permissions.d.ts +141 -0
  277. package/dist/rules/action-route-permissions.d.ts.map +1 -0
  278. package/dist/rules/action-route-permissions.js +556 -0
  279. package/dist/rules/action-route-permissions.js.map +1 -0
  280. package/dist/rules/bundle-pairing.d.ts +74 -0
  281. package/dist/rules/bundle-pairing.d.ts.map +1 -0
  282. package/dist/rules/bundle-pairing.js +281 -0
  283. package/dist/rules/bundle-pairing.js.map +1 -0
  284. package/dist/rules/channel-resolution.d.ts +17 -0
  285. package/dist/rules/channel-resolution.d.ts.map +1 -0
  286. package/dist/rules/channel-resolution.js +382 -0
  287. package/dist/rules/channel-resolution.js.map +1 -0
  288. package/dist/rules/command-coverage.d.ts +210 -0
  289. package/dist/rules/command-coverage.d.ts.map +1 -0
  290. package/dist/rules/command-coverage.js +714 -0
  291. package/dist/rules/command-coverage.js.map +1 -0
  292. package/dist/rules/container-imports.d.ts +60 -0
  293. package/dist/rules/container-imports.d.ts.map +1 -0
  294. package/dist/rules/container-imports.js +158 -0
  295. package/dist/rules/container-imports.js.map +1 -0
  296. package/dist/rules/default-language-prose.d.ts +212 -0
  297. package/dist/rules/default-language-prose.d.ts.map +1 -0
  298. package/dist/rules/default-language-prose.js +710 -0
  299. package/dist/rules/default-language-prose.js.map +1 -0
  300. package/dist/rules/diacritic-folds.d.ts +238 -0
  301. package/dist/rules/diacritic-folds.d.ts.map +1 -0
  302. package/dist/rules/diacritic-folds.js +681 -0
  303. package/dist/rules/diacritic-folds.js.map +1 -0
  304. package/dist/rules/entity-tenant-classification.d.ts +171 -0
  305. package/dist/rules/entity-tenant-classification.d.ts.map +1 -0
  306. package/dist/rules/entity-tenant-classification.js +323 -0
  307. package/dist/rules/entity-tenant-classification.js.map +1 -0
  308. package/dist/rules/entry-presence.d.ts +142 -0
  309. package/dist/rules/entry-presence.d.ts.map +1 -0
  310. package/dist/rules/entry-presence.js +339 -0
  311. package/dist/rules/entry-presence.js.map +1 -0
  312. package/dist/rules/entry-scope.d.ts +91 -0
  313. package/dist/rules/entry-scope.d.ts.map +1 -0
  314. package/dist/rules/entry-scope.js +404 -0
  315. package/dist/rules/entry-scope.js.map +1 -0
  316. package/dist/rules/env-inputs.d.ts +222 -0
  317. package/dist/rules/env-inputs.d.ts.map +1 -0
  318. package/dist/rules/env-inputs.js +951 -0
  319. package/dist/rules/env-inputs.js.map +1 -0
  320. package/dist/rules/kernel-boundary.d.ts +37 -0
  321. package/dist/rules/kernel-boundary.d.ts.map +1 -0
  322. package/dist/rules/kernel-boundary.js +195 -0
  323. package/dist/rules/kernel-boundary.js.map +1 -0
  324. package/dist/rules/nul-bytes.d.ts +233 -0
  325. package/dist/rules/nul-bytes.d.ts.map +1 -0
  326. package/dist/rules/nul-bytes.js +332 -0
  327. package/dist/rules/nul-bytes.js.map +1 -0
  328. package/dist/rules/platform-surface.d.ts +479 -0
  329. package/dist/rules/platform-surface.d.ts.map +1 -0
  330. package/dist/rules/platform-surface.js +749 -0
  331. package/dist/rules/platform-surface.js.map +1 -0
  332. package/dist/rules/port-catches.d.ts +225 -0
  333. package/dist/rules/port-catches.d.ts.map +1 -0
  334. package/dist/rules/port-catches.js +1374 -0
  335. package/dist/rules/port-catches.js.map +1 -0
  336. package/dist/rules/port-shape.d.ts +213 -0
  337. package/dist/rules/port-shape.d.ts.map +1 -0
  338. package/dist/rules/port-shape.js +670 -0
  339. package/dist/rules/port-shape.js.map +1 -0
  340. package/dist/rules/queue-names.d.ts +108 -0
  341. package/dist/rules/queue-names.d.ts.map +1 -0
  342. package/dist/rules/queue-names.js +395 -0
  343. package/dist/rules/queue-names.js.map +1 -0
  344. package/dist/rules/singleton-identity.d.ts +205 -0
  345. package/dist/rules/singleton-identity.d.ts.map +1 -0
  346. package/dist/rules/singleton-identity.js +830 -0
  347. package/dist/rules/singleton-identity.js.map +1 -0
  348. package/dist/rules/subscribe-seam.d.ts +121 -0
  349. package/dist/rules/subscribe-seam.d.ts.map +1 -0
  350. package/dist/rules/subscribe-seam.js +594 -0
  351. package/dist/rules/subscribe-seam.js.map +1 -0
  352. package/dist/rules/transaction-context.d.ts +40 -0
  353. package/dist/rules/transaction-context.d.ts.map +1 -0
  354. package/dist/rules/transaction-context.js +294 -0
  355. package/dist/rules/transaction-context.js.map +1 -0
  356. 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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"}