@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,329 @@
1
+ /**
2
+ * `endora new storefront <dir>` — the command.
3
+ *
4
+ * It copies the reference storefront out of this repository into a directory the
5
+ * client then owns outright, rewrites every declaration that names something
6
+ * above the storefront's own directory, and **forgets it** (D-195). There is no
7
+ * kit, no shell and no channel back to what it wrote: a scaffold that kept one
8
+ * would be a kit wearing a different name.
9
+ *
10
+ * The order is `endora new module`'s and for the same reason: **validate
11
+ * completely, then write**. A half-written storefront is worse than none — it
12
+ * installs against ranges nothing resolves, its configuration extends a file it
13
+ * does not have, and the author's next command is a manual clean-up.
14
+ *
15
+ * Exit codes are `contracts/cli-surface.md` §2's, unchanged: `0` it did what it
16
+ * was asked, `1` a refusal the author can act on, `2` an input it could not
17
+ * read. The three refusal classes map cleanly — a target directory that is
18
+ * occupied and an outward reference no rule classifies are `1`; a checkout with
19
+ * no reference storefront in it is `2`.
20
+ *
21
+ * ## It resolves the copy's environment inputs, in four tiers
22
+ *
23
+ * `specs/117-instance-bring-up/` FR-010…FR-015. The storefront declares what it
24
+ * needs (`storefront/environment-inputs.mjs`) and this command resolves each of
25
+ * those in one fixed order — an explicit flag, then a `.env` already placed in
26
+ * the target directory, then a prompt on a terminal, then a refusal naming
27
+ * **every** missing input at once — and writes the answers into the copy's own
28
+ * `.env`. The values are the operator's or they are asked for; nothing is
29
+ * invented, and the run says so in a provenance line whose `defaulted=` is
30
+ * contract-bound to `0`.
31
+ *
32
+ * FR-014 is why it is here and not only in `endora new instance`: one product
33
+ * means one behaviour, and the resolution is one shared module rather than a
34
+ * copy per command. This command already exists and already has a customer, and
35
+ * three of its required inputs are three of the four facts nothing reconciles
36
+ * across the trees today.
37
+ */
38
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
39
+ import { dirname, isAbsolute, join, resolve, sep } from 'node:path';
40
+ import { scopeToMembers } from '@endora-commerce/contracts';
41
+ import { loadTreeDeclaration } from '../inputs/declaration.js';
42
+ import { parseEnvFile, writeEnvFile } from '../inputs/env-file.js';
43
+ import { promptForInputs } from '../inputs/prompt.js';
44
+ import { flagFor, generateSecret, interactivityOf, missingInputsRefusal, planResolution, provenanceLine, } from '../inputs/resolve.js';
45
+ import { TOKEN_VARIABLE } from './npmrc.js';
46
+ import { addressVariables, ENV_EXAMPLE_FILE, memberDirectories, resolveReference, STOREFRONT_DECLARATION_EXPORT, StorefrontHostError, StorefrontInputError, } from './reference.js';
47
+ import { planStorefront } from './rewrite.js';
48
+ /** Raised when required inputs are missing and this run may not ask (R7.2). */
49
+ export class MissingInputsError extends Error {
50
+ name = 'MissingInputsError';
51
+ }
52
+ export async function runNewStorefront(options) {
53
+ const cwd = options.cwd ?? process.cwd();
54
+ if (options.dir === undefined || options.dir.trim().length === 0) {
55
+ throw new StorefrontInputError(`\`new storefront\` takes the directory to write, and has no default. The reference ` +
56
+ `storefront is this repository's own application; a command that defaulted the target ` +
57
+ `would either overwrite it or invent a name nobody chose.`);
58
+ }
59
+ const reference = resolveReference(cwd);
60
+ const targetDir = isAbsolute(options.dir) ? options.dir : resolve(cwd, options.dir);
61
+ refuseOccupiedDirectory(targetDir);
62
+ if (targetDir === reference.dir || targetDir.startsWith(reference.dir + sep)) {
63
+ throw new StorefrontInputError(`${targetDir} is inside the reference storefront this command copies. A scaffold written ` +
64
+ `there would be a copy of itself, and the copy would be part of its own population on ` +
65
+ `the next run.`);
66
+ }
67
+ const members = memberDirectories(reference.repoRoot);
68
+ const plan = planStorefront(reference, members, targetDir, {
69
+ ...(options.registry === undefined ? {} : { registry: options.registry }),
70
+ });
71
+ // Validate completely, then write — and the inputs are part of "completely".
72
+ // A tree written before the refusal would be a storefront on disk that cannot
73
+ // build, which is the half-written state this command's whole order exists to
74
+ // avoid.
75
+ const dryRun = options.dryRun === true;
76
+ const interactivity = interactivityOf({
77
+ nonInteractive: options.nonInteractive === true,
78
+ dryRun,
79
+ });
80
+ const declared = await loadTreeDeclaration(reference.dir, STOREFRONT_DECLARATION_EXPORT);
81
+ const resolution = planResolution({
82
+ declared,
83
+ // `endora new storefront` writes exactly one member. An input read only by
84
+ // the admin or only by the backend is out of this run's population — not
85
+ // resolved, not asked for, not refused — which is
86
+ // `specs/118-instance-member-selection/`'s scoping, applied to the command
87
+ // that has one member today so that it is already right for the command
88
+ // that has three tomorrow.
89
+ members: ['storefront'],
90
+ flags: options.inputs ?? {},
91
+ envFile: readTargetEnv(targetDir),
92
+ interactivity,
93
+ language: 'en',
94
+ });
95
+ if (resolution.missing.length > 0) {
96
+ throw new MissingInputsError(missingInputsRefusal(resolution.missing, interactivity));
97
+ }
98
+ if (dryRun) {
99
+ // R2.4 / R7.3 — a dry run resolves and reports; it prompts nothing and
100
+ // generates nothing, and it names each input it would have had to ask for.
101
+ // Its purpose is to be inspectable before it is trusted, and a dry run that
102
+ // stopped to ask for a password is not inspectable.
103
+ return {
104
+ reference,
105
+ targetDir,
106
+ plan,
107
+ dryRun: true,
108
+ nextSteps: nextSteps(targetDir, plan, declared, resolution.resolved),
109
+ resolved: resolution.resolved,
110
+ provenance: provenanceLine(resolution.resolved),
111
+ wouldPrompt: resolution.toPrompt.map((input) => input.name),
112
+ wouldGenerate: resolution.toGenerate.map((input) => input.name),
113
+ unset: resolution.unset.map((input) => input.name),
114
+ };
115
+ }
116
+ const answered = await promptForInputs(resolution.toPrompt, 'en', options.promptIo ?? { input: process.stdin, output: process.stdout });
117
+ const generated = resolution.toGenerate.map((input) => ({
118
+ name: input.name,
119
+ value: generateSecret(),
120
+ provenance: 'generated',
121
+ }));
122
+ const resolved = [...resolution.resolved, ...answered, ...generated];
123
+ for (const file of plan.files) {
124
+ const target = join(targetDir, file.path);
125
+ mkdirSync(dirname(target), { recursive: true });
126
+ if (file.content !== null)
127
+ writeFileSync(target, file.content, 'utf8');
128
+ else
129
+ writeFileSync(target, readFileSync(file.source));
130
+ }
131
+ writeResolvedEnv(targetDir, resolved);
132
+ return {
133
+ reference,
134
+ targetDir,
135
+ plan,
136
+ dryRun: false,
137
+ nextSteps: nextSteps(targetDir, plan, declared, resolved),
138
+ resolved,
139
+ provenance: provenanceLine(resolved),
140
+ wouldPrompt: [],
141
+ wouldGenerate: [],
142
+ unset: resolution.unset.map((input) => input.name),
143
+ };
144
+ }
145
+ /**
146
+ * The flags this build accepts for the reference storefront's declared inputs,
147
+ * without their leading dashes.
148
+ *
149
+ * The argv layer calls this **before** it parses, so `parseArgs` keeps
150
+ * `strict: true` and an unrecognised flag stays a refusal
151
+ * (`cli-surface.md` §1). The alternative — parsing leniently for this one
152
+ * subcommand — would trade a typo'd `--next-public-api-base-ur` from a loud
153
+ * refusal into a silently unset required input, which is the whole class of
154
+ * failure this feature exists to remove.
155
+ *
156
+ * It is derived from the declaration rather than written down, so a storefront
157
+ * that declares a variable this build has never heard of is supplied by its own
158
+ * flag with nothing here to update (D-100).
159
+ */
160
+ export async function storefrontInputFlags(cwd) {
161
+ return (await storefrontDeclaredInputs(cwd)).map((input) => flagFor(input.name).slice(2));
162
+ }
163
+ /**
164
+ * The reference storefront's own declaration, scoped to the one member this
165
+ * command writes.
166
+ *
167
+ * Exported because a caller that has to *supply* these inputs needs the same
168
+ * population the command will *demand*, and deriving it twice is two answers
169
+ * waiting to disagree — which is exactly how the acceptance criterion came to
170
+ * invoke this command with none of them. The scoping is `planResolution`'s and
171
+ * is applied here so that the two cannot part company either: an input read only
172
+ * by the admin or only by the backend is out of this command's population, so it
173
+ * is out of a supplier's too.
174
+ *
175
+ * The requirement is deliberately **not** filtered here. `isRequiredGiven` reads
176
+ * a conditional requirement against the values a run has in hand, so which
177
+ * inputs are required is a property of the invocation rather than of the
178
+ * declaration, and answering it here would answer it for one invocation and be
179
+ * wrong for the next.
180
+ */
181
+ export async function storefrontDeclaredInputs(cwd) {
182
+ const reference = resolveReference(cwd);
183
+ const declared = await loadTreeDeclaration(reference.dir, STOREFRONT_DECLARATION_EXPORT);
184
+ return scopeToMembers(declared, ['storefront']);
185
+ }
186
+ /** The file the copy's own runtime configuration lives in. */
187
+ const ENV_FILE = '.env';
188
+ /**
189
+ * Tier 2 — the `.env` **of the target directory**, never of the working
190
+ * directory and never of an ancestor (R1.2).
191
+ *
192
+ * That restriction is the whole of the rule: a command run inside a checkout of
193
+ * ours must not silently inherit that checkout's development configuration,
194
+ * which is how a client's first instance would come to carry
195
+ * `postgresql://b2b:b2b@localhost:5432/b2b`.
196
+ */
197
+ function readTargetEnv(targetDir) {
198
+ const path = join(targetDir, ENV_FILE);
199
+ if (!existsSync(path))
200
+ return new Map();
201
+ return parseEnvFile(readFileSync(path, 'utf8'));
202
+ }
203
+ /**
204
+ * The answers, into the copy's own `.env`.
205
+ *
206
+ * R4.2 — a generated secret is written **where the operator can read it**,
207
+ * change it and copy it into a secret store. It is named in the provenance line
208
+ * and its value is printed nowhere.
209
+ *
210
+ * The file the operator may already have placed here is merged into rather than
211
+ * rewritten: its comments, its ordering and its own keys survive.
212
+ */
213
+ function writeResolvedEnv(targetDir, resolved) {
214
+ const path = join(targetDir, ENV_FILE);
215
+ const existing = existsSync(path) ? readFileSync(path, 'utf8') : '';
216
+ const values = new Map(resolved.map((entry) => [entry.name, entry.value]));
217
+ writeFileSync(path, writeEnvFile(existing, values), 'utf8');
218
+ }
219
+ /**
220
+ * The target must be empty — **or hold nothing but a `.env`**.
221
+ *
222
+ * The exception is the owner's own second tier, in their own words: *"I invoke a
223
+ * command and I can attach arguments, **or place the required things in a
224
+ * `.env` beforehand**"*. Without it tier 2 is unreachable for this command,
225
+ * because the only directory it accepts is one that can hold no file at all —
226
+ * which would leave `input-resolution.md` §1's four tiers implemented as three
227
+ * and the operator's cheapest path refused by the command that documents it.
228
+ *
229
+ * It stays one file rather than "a few harmless ones". Everything else this
230
+ * command would write over is either hand-written code or a copy of the
231
+ * reference, and merging into either is the silent discard the refusal exists
232
+ * for; a `.env` is neither, being the one file whose contents this command reads
233
+ * *before* it writes and merges into rather than replaces.
234
+ */
235
+ function refuseOccupiedDirectory(targetDir) {
236
+ if (!existsSync(targetDir))
237
+ return;
238
+ const entries = readdirSync(targetDir);
239
+ if (entries.length === 0)
240
+ return;
241
+ if (entries.length === 1 && entries[0] === ENV_FILE)
242
+ return;
243
+ throw new StorefrontInputError(`${targetDir} exists and is not empty (${entries.slice(0, 5).join(', ')}). This command ` +
244
+ `never merges into a directory: it is not idempotent over an existing storefront, and ` +
245
+ `pretending otherwise would silently discard hand-written code. A directory holding ` +
246
+ `nothing but a \`${ENV_FILE}\` is the one exception — that file is where you may place ` +
247
+ `the values this command would otherwise ask you for.`);
248
+ }
249
+ /**
250
+ * The steps that are the author's.
251
+ *
252
+ * It never runs them, for `endora new module`'s reason: a scaffold that ran the
253
+ * consuming project's tooling would be a channel back to the instance, and D-195
254
+ * is that there is none.
255
+ *
256
+ * **The first step is about the registry, and it changed with publication**
257
+ * (feature 104, § 1.5). It used to tell its reader to pack tarballs and pin them
258
+ * through `pnpm.overrides`, which was honest while nothing under `packages/` was
259
+ * published and became wrong the moment something was — instructions in a copy a
260
+ * client owns outright are not something anybody comes back to correct.
261
+ */
262
+ function nextSteps(targetDir, plan, declared, resolved) {
263
+ const published = plan.ranges.length;
264
+ const ranges = `the ${String(published)} \`@endora-commerce/*\` ${published === 1 ? 'range' : 'ranges'}`;
265
+ const install = plan.registry === null
266
+ ? `cd ${targetDir} && pnpm install — ${ranges} in the manifest are published semver and ` +
267
+ `resolve at the public npm registry, which is what this command assumes when it is not ` +
268
+ `told otherwise. If your instance installs them from a private registry, scaffold again ` +
269
+ `with \`--registry <url>\`: it writes the \`.npmrc\` for you, with the token as an ` +
270
+ `environment reference and never as a value.`
271
+ : `cd ${targetDir} && export ${TOKEN_VARIABLE}=… && pnpm install — the \`.npmrc\` this ` +
272
+ `command wrote points ${ranges} at ${plan.registry}. The file holds no secret: the ` +
273
+ `token is \${${TOKEN_VARIABLE}}, expanded at install time, so commit the file and keep ` +
274
+ `the value in your environment. If a fetch reports that a package "is not in the npm ` +
275
+ `registry", read the last line of pnpm's output before believing it — the registry ` +
276
+ `answers an expired credential with 404, in the same words it uses for a package that ` +
277
+ `genuinely does not exist.`;
278
+ // The names are the copy's own declaration, never a pair written here: this
279
+ // step used to name `PUBLIC_API_BASE_URL`, which nothing in the storefront
280
+ // reads, and the fetchers fall back to `http://localhost:3001` in silence — so
281
+ // an author who followed it had a storefront talking to nothing in particular
282
+ // and no error anywhere to say so.
283
+ //
284
+ // **It is `addressOf`, not the shape of the value in `.env.example`.** That
285
+ // was the derivation until `NEXT_PUBLIC_SITE_URL` was supplied there, at which
286
+ // point a predicate reading *absolute `http(s)` URL* would have swept the
287
+ // shop's **own** public address into this sentence and told its owner it
288
+ // "names the backend this storefront talks to" — in a file they own outright
289
+ // and nobody comes back to correct.
290
+ const backendVariables = addressVariables(declared, 'backend');
291
+ // Which of those the run already answered. The step below stops telling an
292
+ // author to set a value that is already in the file this command wrote:
293
+ // instructions in a copy the client owns outright are not something anybody
294
+ // comes back to correct, so a stale one stays wrong for the life of the shop.
295
+ const answered = new Set(resolved.map((entry) => entry.name));
296
+ // Next's own convention, not ours: a `NEXT_PUBLIC_` variable is inlined into
297
+ // the client bundle by `next build`, so setting it afterwards changes nothing
298
+ // a browser sees. Saying which of the copy's variables that is costs a prefix
299
+ // test and saves the author a rebuild they would otherwise discover.
300
+ const baked = backendVariables.filter((name) => name.startsWith('NEXT_PUBLIC_'));
301
+ const unanswered = backendVariables.filter((name) => !answered.has(name));
302
+ const backendStep = () => unanswered.length === 0
303
+ ? `check ${ENV_FILE} — this command wrote it, and every value in it is one you supplied ` +
304
+ `on the command line, one you had already put there, or one you were asked for. ` +
305
+ `${backendVariables.length === 0 ? '' : `${backendVariables.join(' and ')} name the ` +
306
+ `backend this storefront talks to; change ${backendVariables.length === 1 ? 'it' : 'them'} there. `}Nothing in it was invented — a generated secret is named in the ` +
307
+ `\`[inputs] resolved:\` line above and its value is in the file, never on your screen.`
308
+ : `set ${unanswered.join(' and ')} (and the rest of ${ENV_EXAMPLE_FILE}) to the ` +
309
+ `backend this storefront talks to. Its fetchers fall back to a compiled-in address when ` +
310
+ `the environment names none, so an instance that sets none of them talks to that ` +
311
+ `address rather than refusing.${baked.length === 0 ? '' : ` Next inlines ${baked.join(' and ')} into the browser bundle at build time, so set ${baked.length === 1 ? 'it' : 'them'} before \`pnpm run build\` rather than after.`}`;
312
+ return [
313
+ install,
314
+ backendStep(),
315
+ `pnpm run build — it runs \`themes:generate\`, \`next build\` and \`check:themes\`.`,
316
+ // Baseline step E4 (`specs/125-first-mile-install/spec.md` §2.3), which was
317
+ // printed nowhere: `storefront/package.json` has declared `start` all
318
+ // along, and a client who followed this block to the end had a built
319
+ // storefront and no command to serve it with.
320
+ `pnpm run start — the built storefront, served. \`pnpm run dev\` is the other one: the ` +
321
+ `same pages, rebuilt as you edit them, and the only one of the two that does not need a ` +
322
+ `build first.`,
323
+ `this storefront is yours now. There is no kit to upgrade and no shell to keep in step: a ` +
324
+ `fix to the platform reaches you through \`@endora-commerce/contracts\`, where a wire ` +
325
+ `change is a compile error rather than a runtime surprise.`,
326
+ ];
327
+ }
328
+ export { StorefrontHostError, StorefrontInputError };
329
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/new-storefront/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * The environment variable the auth line refers to.
3
+ *
4
+ * One name, spelled here and in `.gitlab-ci.yml`'s `publish:packages` job,
5
+ * because it is the name the contract writes (R3) and the one an operator is told
6
+ * to set. It is deliberately not an option: a per-scaffold variable name is a
7
+ * support conversation per client for no capability.
8
+ */
9
+ export declare const TOKEN_VARIABLE = "ENDORA_NPM_TOKEN";
10
+ /**
11
+ * The registry URL as an `.npmrc` line writes it: absolute, `http(s)`, with the
12
+ * trailing slash GitLab's own troubleshooting requires (R3.2).
13
+ */
14
+ export declare function normalizeRegistry(registry: string): string;
15
+ /**
16
+ * The scopes a scaffolded storefront installs from a registry.
17
+ *
18
+ * Read off the reference storefront's `workspace:` ranges — the packages that
19
+ * stop resolving the moment the copy leaves the workspace — rather than off the
20
+ * checkout's members. The two populations are not the same question: what the
21
+ * platform *publishes* is `check:release-intent`'s, and what this storefront
22
+ * *installs* is this one's.
23
+ */
24
+ export declare function installedScopes(manifest: Record<string, unknown>): readonly string[];
25
+ /**
26
+ * The keys the auth lines are written under: the endpoint, and the host it is on.
27
+ *
28
+ * Both are npm's own spelling for a credential — the request URL with its scheme
29
+ * removed — and both matter, for two different fetches.
30
+ *
31
+ * **The endpoint key** is the narrowest key covering the one address the operator
32
+ * actually named, and it is what GitLab's own documentation writes. It is kept
33
+ * rather than replaced by the broader one below: pnpm was measured walking a
34
+ * request path upward — a key on `//host/api/v4/` authenticates a tarball under
35
+ * `/api/v4/projects/…` — so for pnpm the endpoint key is redundant, and a client
36
+ * matching these keys **exactly** would still authenticate the packument with it.
37
+ * No such client was measured here, so the honest reason to keep the line is the
38
+ * smaller one: dropping it would make the file say less than it knows about the
39
+ * one address the operator gave.
40
+ *
41
+ * **The host key** is the one that covers a tarball. It is broad on purpose: the
42
+ * tarball URL is chosen by the server and appears for the first time inside a
43
+ * packument this file will never see, so the only statically derivable key
44
+ * guaranteed to cover it is the whole host. Measured with a local registry
45
+ * standing in for GitLab's shape — a packument served on the endpoint whose
46
+ * `dist.tarball` names `/api/v4/projects/302/packages/npm/…` on the same host —
47
+ * under pnpm 9.15.0, the version CI pins, and under pnpm 10:
48
+ *
49
+ * endpoint key alone ERR_PNPM_FETCH_404 … Not Found - 404
50
+ * "No authorization header was set for the request."
51
+ * endpoint + host key the tarball request carries the header; the install
52
+ * completes.
53
+ *
54
+ * ### Why not a narrower prefix
55
+ *
56
+ * Not because a narrower one would fail — measured, `//host/api/v4/` and
57
+ * `//host/api/v4/projects/` both authenticate that same tarball, because pnpm
58
+ * walks a request's path upward looking for a key. The mechanism is not the
59
+ * obstacle; the **derivation** is. Getting `/api/v4/` out of
60
+ * `/api/v4/packages/npm/` means knowing GitLab's URL layout, which is trading one
61
+ * unexamined premise about the server for a narrower one — and `--registry` names
62
+ * *a registry*, not *a GitLab*: the flag is documented as the endpoint the
63
+ * storefront installs from, and a Verdaccio or an Artifactory behind it has its
64
+ * own layout. `ENDORA_NPM_REGISTRY` is masked and may be the instance endpoint or
65
+ * a group one, so the file cannot even be written against one observed shape.
66
+ *
67
+ * ### What is given up, stated rather than glossed
68
+ *
69
+ * The credential is offered to **every** request pnpm makes to this host and
70
+ * port, not only to the endpoint's own subtree. That is broader than the single
71
+ * line this file used to write. It is accepted because the host is the one the
72
+ * operator named on the command line, the credential a client is handed is a
73
+ * deploy token scoped `read_package_registry` (R3.3) whose whole authority on
74
+ * that host is reading packages, and the alternative — the credential not
75
+ * reaching the address the registry itself directed the client to — is an install
76
+ * that cannot work.
77
+ *
78
+ * And what it does **not** cover, so nobody reads it as more than it is: a
79
+ * registry that serves tarballs from a **different host** (a CDN, a storage
80
+ * bucket) is not reached by this key or by any other one derivable here, because
81
+ * that host appears nowhere in the input. Such a registry needs a line naming it,
82
+ * and the symptom would be this same 404 on the tarball alone.
83
+ *
84
+ * A registry configured at the root of its host makes the two keys identical, and
85
+ * then there is one line rather than two: a duplicate would not be wrong, it
86
+ * would read as though it said something.
87
+ */
88
+ export declare function authKeys(registry: string): readonly string[];
89
+ /**
90
+ * The file's text: one registry line per scope, and the auth lines `authKeys`
91
+ * derives.
92
+ *
93
+ * There is one set of auth lines however many scopes there are, because a
94
+ * credential is a property of the endpoint rather than of a scope — the half of
95
+ * this file's original reasoning that survived the measurement above.
96
+ */
97
+ export declare function npmrcContent(registry: string, scopes: readonly string[]): string;
98
+ //# sourceMappingURL=npmrc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npmrc.d.ts","sourceRoot":"","sources":["../../src/new-storefront/npmrc.ts"],"names":[],"mappings":"AAoDA;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2C1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,MAAM,EAAE,CAQpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAK5D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAwBhF"}