@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,556 @@
1
+ /**
2
+ * CI check — a manifest action's `requiredPermission` is the code enforced on
3
+ * the route behind its own `targetRoute` (issue #232; Principle XVI item 2, "the
4
+ * code gating the target surface, so the palette never advertises a 403").
5
+ *
6
+ * `test/contract/admin_users/permission-inventory.test.ts` already sweeps two
7
+ * directions — every enforced code is grantable, every grantable code is
8
+ * enforced — and **both** of the defects that produced this check passed it,
9
+ * because both codes were real, declared and enforced somewhere:
10
+ *
11
+ * - `settings`' `open-settings` action declared no `requiredPermission` at all
12
+ * while `/api/v1/admin/settings` is `requireAdmin('settings:read')`, so ⌘K
13
+ * offered the screen to every role and every role without the code collected
14
+ * a guaranteed 403;
15
+ * - `inventory`' `open-inventory` declared `catalog:write` while
16
+ * `/api/v1/admin/inventory` is `requireAdmin('orders:read')` — wrong in both
17
+ * directions at once, hiding the screen from operators who can open it and
18
+ * offering it to some who cannot.
19
+ *
20
+ * Neither is visible to a sweep over the *set* of codes. The third direction —
21
+ * the code is the one enforced on **this action's** target — is what this check
22
+ * adds.
23
+ *
24
+ * ## What "agrees" means
25
+ *
26
+ * Permission codes are opaque: `hasPermission(userId, code)` compares strings
27
+ * (plus the `'*'` wildcard), so `catalog:write` does not imply `catalog:read`.
28
+ * The property is therefore **sufficiency**, not equality: *holding the declared
29
+ * code, and nothing else, must be enough to open the target screen.* For
30
+ * `requireAdmin('x')` that collapses to equality; for
31
+ * `requireAdminAny(['customers:read', 'customers:manage'])` — the one any-of
32
+ * gate in the tree — either member is sufficient and either is accepted.
33
+ *
34
+ * Sufficiency leaves one residue, deliberately: an action naming one member of
35
+ * an any-of gate is hidden from an operator holding only the other member. That
36
+ * is under-advertising, not a 403, and the manifest field is a single code, so
37
+ * the palette cannot express the alternative. The sidebar can (MR !736 gave
38
+ * `NavItem.requiredPermission` an any-of array for exactly this route); a
39
+ * manifest action cannot, and widening the contract for one route is not
40
+ * something this check should force.
41
+ *
42
+ * ## Which route is "the" route
43
+ *
44
+ * A `targetRoute` is an admin SPA path (`/inventory`), not an API path
45
+ * (`/api/v1/admin/inventory`), and nothing in the tree declares the link. The
46
+ * check reconstructs it as the **entry route**: the request the browser must be
47
+ * allowed to make for the screen to render at all. Resolution runs in levels,
48
+ * first non-empty level wins, and stops at the first level that answers:
49
+ *
50
+ * 1. **exact** — a registration at `/api/v1/admin` + the target;
51
+ * 2. **subtree** — the shallowest registrations under it, for a screen whose
52
+ * data hangs off sub-resources (`/custom-fields` →
53
+ * `/api/v1/admin/custom-fields/definitions`);
54
+ * 3. **module** — the shallowest registrations the owning module ships at all,
55
+ * for a screen whose SPA placement is not its API path (`/settings/stripe`
56
+ * is placed under Settings; its API is `/api/v1/admin/stripe/config`).
57
+ *
58
+ * An action targeting `/x/new` is a create form, so the parent path is resolved
59
+ * instead and the method class flips from GET to the write verbs: the gate that
60
+ * decides whether that form can be submitted is the POST's, not the list's.
61
+ *
62
+ * Where the shallowest candidates disagree on their gate, or where a selected
63
+ * gate is a `preHandler` the scanner cannot read, the action is reported
64
+ * `unresolvable` rather than compared against a guess. An entry route that gates
65
+ * on **no** code accepts any declaration: holding a code the route does not ask
66
+ * for still opens the screen, so it cannot produce a 403 — it can only
67
+ * under-advertise, and no shipped action does.
68
+ *
69
+ * What the check cannot settle is where the label promises a write and the
70
+ * screen opens on a read: one field cannot say both codes, and
71
+ * `ACTION_PERMISSION_DISAGREEMENTS` holds those three with the question that
72
+ * would retire each.
73
+ *
74
+ * ## The artefact this reads, and when it refuses to judge it
75
+ *
76
+ * The route half is source text, walked. The **manifest** half is imported, and
77
+ * a module that has become a workspace package resolves through its own
78
+ * `exports` map at its build output (D-164) — so an action edited in
79
+ * `packages/modules/<id>/src/manifest.ts` and not rebuilt is not the action
80
+ * this check sees. Measured three consecutive times on
81
+ * `specs/091-module-owned-admin-surfaces/`'s admin drain, most sharply on
82
+ * !1203, where a `requiredPermission` changed from `payu:read` to `payu:write`
83
+ * reported `findings=3 violations=0` and exit 0 before
84
+ * `pnpm --filter @endora-commerce/mod-payu run build`, and `findings=4
85
+ * violations=1` and exit 1 after it. So a run whose manifest artefact is older
86
+ * than the source it was emitted from **exits 2** and names the package: the
87
+ * tree is not in violation, this run could not see it. See
88
+ * `scripts/lib/emitted-freshness.ts`, where the derivation lives, and the
89
+ * `emitted-manifests` token on the `read:` line, which is how a clean run says
90
+ * which artefact it read.
91
+ *
92
+ * Usage: `tsx scripts/check-action-route-permissions.ts [--list]`
93
+ * Exit 0 = every action's declared code is the one its target enforces (or the
94
+ * disagreement is ledgered); exit 1 = at least one is not, or a ledger entry is
95
+ * stale; exit 2 = the scan read no route or no action, or the manifest artefact
96
+ * it read has been outrun by its source — a green would have meant "not
97
+ * looking" (issue #113).
98
+ *
99
+ * ## One analysis, two hosts
100
+ *
101
+ * This file is the analysis (`specs/101-endora-check/contracts/package-scope-layout.md`
102
+ * §6). `backend/scripts/check-action-route-permissions.ts` hosts it over this
103
+ * repository's module walk roots, its overlay root and its emitted manifests,
104
+ * and holds `ACTION_PERMISSION_DISAGREEMENTS` — a ledger of *this* tree's owner
105
+ * decisions, which is why the ledger is an argument rather than a value this
106
+ * file reads.
107
+ *
108
+ * `endora check`'s host lands with Phase 3 and its estate entry says why, with
109
+ * the measurement: half this estate writes a permission code as a module-level
110
+ * constant, the reader that follows one is `admin_roles`' `ConstantResolver`,
111
+ * and no module package can reach it. Without it 27 gates in 11 of the 70
112
+ * module packages read as `unreadable` — findings about correct code, which
113
+ * §5.1 refuses.
114
+ */
115
+ import { existsSync, readdirSync, statSync } from 'node:fs';
116
+ import { join } from 'node:path';
117
+ import ts from 'typescript';
118
+ import { moduleIdOf as segmentModuleIdOf, NO_HOST_RESIDENT_MODULES, } from '../lib/module-population.js';
119
+ /** Every admin API path starts here; nothing else is an admin surface. */
120
+ const ADMIN_API_PREFIX = '/api/v1/admin';
121
+ /** The Fastify shorthand methods a route registration can be written as. */
122
+ const ROUTE_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete']);
123
+ /** The verbs a create form submits through — the write half of a surface. */
124
+ const WRITE_METHODS = new Set(['post', 'put', 'patch', 'delete']);
125
+ /** The guard family whose argument is a permission code. */
126
+ const GUARD_NAMES = new Set(['requireAdmin', 'requireAdminAny']);
127
+ // ---------------------------------------------------------------------------
128
+ // Route extraction
129
+ // ---------------------------------------------------------------------------
130
+ /** The trailing identifier of a callee: `deps.requireAdmin` → `requireAdmin`. */
131
+ function tailName(node) {
132
+ if (ts.isIdentifier(node))
133
+ return node.text;
134
+ if (ts.isPropertyAccessExpression(node))
135
+ return node.name.text;
136
+ if (ts.isAsExpression(node) ||
137
+ ts.isNonNullExpression(node) ||
138
+ ts.isParenthesizedExpression(node)) {
139
+ return tailName(node.expression);
140
+ }
141
+ return null;
142
+ }
143
+ /** The string a node denotes, through casts. Template literals are handled apart. */
144
+ function stringLiteralOf(node) {
145
+ if (ts.isStringLiteralLike(node) && !ts.isTemplateExpression(node))
146
+ return node.text;
147
+ if (ts.isAsExpression(node) ||
148
+ ts.isNonNullExpression(node) ||
149
+ ts.isParenthesizedExpression(node)) {
150
+ return stringLiteralOf(node.expression);
151
+ }
152
+ return null;
153
+ }
154
+ /** Every `const x = <initialiser>` in a file, by name — the local scope this reads. */
155
+ function localBindings(sf) {
156
+ const bindings = new Map();
157
+ const visit = (node) => {
158
+ if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
159
+ // First writer wins: a name re-bound in an inner scope is the exception,
160
+ // and taking the outer one keeps the answer stable across files.
161
+ if (!bindings.has(node.name.text))
162
+ bindings.set(node.name.text, node.initializer);
163
+ }
164
+ node.forEachChild(visit);
165
+ };
166
+ sf.forEachChild(visit);
167
+ return bindings;
168
+ }
169
+ /**
170
+ * The path a route registration's first argument denotes.
171
+ *
172
+ * Two spellings appear: a plain literal, and a template whose head is a
173
+ * module-local `const base = '/api/v1/admin/<module>'` (`newsletter`,
174
+ * `transactional_emails`). A span that cannot be resolved yields `null` — the
175
+ * registration is then not attributed to any target, and the run says how many
176
+ * such there were rather than quietly shrinking the population.
177
+ */
178
+ function routePathOf(node, bindings) {
179
+ const literal = stringLiteralOf(node);
180
+ if (literal !== null)
181
+ return literal;
182
+ if (ts.isTemplateExpression(node)) {
183
+ let out = node.head.text;
184
+ for (const span of node.templateSpans) {
185
+ const name = ts.isIdentifier(span.expression) ? span.expression.text : null;
186
+ const bound = name === null ? undefined : bindings.get(name);
187
+ const value = bound === undefined ? null : stringLiteralOf(bound);
188
+ if (value === null)
189
+ return null;
190
+ out += value + span.literal.text;
191
+ }
192
+ return out;
193
+ }
194
+ return null;
195
+ }
196
+ /** The permission codes a guard call requires, as one clause, or `null`. */
197
+ function clauseOfGuardCall(call, file, input) {
198
+ const [argument] = call.arguments;
199
+ if (argument === undefined)
200
+ return []; // `requireAdmin()` — any authenticated admin.
201
+ const absolute = input.absolutePathOf?.(file) ?? file;
202
+ const lookup = input.lookupConstant ?? (() => null);
203
+ const codeOf = (node) => {
204
+ const literal = stringLiteralOf(node);
205
+ if (literal !== null)
206
+ return literal;
207
+ if (ts.isIdentifier(node))
208
+ return lookup(absolute, node.text, null);
209
+ if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression)) {
210
+ return lookup(absolute, node.expression.text, node.name.text);
211
+ }
212
+ return null;
213
+ };
214
+ if (ts.isArrayLiteralExpression(argument)) {
215
+ const codes = [];
216
+ for (const element of argument.elements) {
217
+ const code = ts.isSpreadElement(element) ? null : codeOf(element);
218
+ if (code === null)
219
+ return null;
220
+ codes.push(code);
221
+ }
222
+ return codes;
223
+ }
224
+ const code = codeOf(argument);
225
+ return code === null ? null : [code];
226
+ }
227
+ /**
228
+ * The gate a route's options argument installs.
229
+ *
230
+ * The shapes present in the tree, all of them resolved module-locally:
231
+ * `{ preHandler: requireAdmin('code') }` and its `deps.`/cradle receivers, the
232
+ * same through a `const guard = requireAdmin(CODE)` binding, an options object
233
+ * held in a `const read = { preHandler: … }` and passed bare or spread
234
+ * (`{ ...write, bodyLimit }`), and an array of pre-handlers.
235
+ */
236
+ function gateOf(node, file, input, bindings, depth = 0) {
237
+ const text = node === undefined ? '' : node.getText().replace(/\s+/g, ' ').slice(0, 120);
238
+ if (node === undefined || depth > 4)
239
+ return { clauses: node === undefined ? [] : null, text };
240
+ // A handler, not an options object: the registration installs no gate.
241
+ if (ts.isArrowFunction(node) || ts.isFunctionExpression(node))
242
+ return { clauses: [], text: '' };
243
+ if (ts.isIdentifier(node)) {
244
+ const bound = bindings.get(node.text);
245
+ return bound === undefined
246
+ ? { clauses: null, text }
247
+ : { ...gateOf(bound, file, input, bindings, depth + 1), text };
248
+ }
249
+ if (ts.isObjectLiteralExpression(node)) {
250
+ const clauses = [];
251
+ let unreadable = false;
252
+ let sawGateSlot = false;
253
+ for (const property of node.properties) {
254
+ if (ts.isSpreadAssignment(property)) {
255
+ const spread = gateOf(property.expression, file, input, bindings, depth + 1);
256
+ if (spread.clauses === null)
257
+ unreadable = true;
258
+ else if (spread.clauses.length > 0) {
259
+ sawGateSlot = true;
260
+ clauses.push(...spread.clauses);
261
+ }
262
+ continue;
263
+ }
264
+ if (!ts.isPropertyAssignment(property) || property.name.getText() !== 'preHandler')
265
+ continue;
266
+ sawGateSlot = true;
267
+ const handlers = ts.isArrayLiteralExpression(property.initializer)
268
+ ? property.initializer.elements
269
+ : [property.initializer];
270
+ let recognised = false;
271
+ for (const handler of handlers) {
272
+ const clause = clauseOfPreHandler(handler, file, input, bindings, depth + 1);
273
+ if (clause === undefined)
274
+ continue;
275
+ recognised = true;
276
+ if (clause === null)
277
+ unreadable = true;
278
+ else if (clause.length > 0)
279
+ clauses.push(clause);
280
+ }
281
+ if (!recognised)
282
+ unreadable = true;
283
+ }
284
+ if (unreadable)
285
+ return { clauses: null, text };
286
+ return { clauses: sawGateSlot ? clauses : [], text: sawGateSlot ? text : '' };
287
+ }
288
+ return { clauses: null, text };
289
+ }
290
+ /**
291
+ * One pre-handler's clause: `null` when it is a guard whose code cannot be read,
292
+ * `undefined` when it is not a permission guard at all (an ETag validator, a
293
+ * rate limiter — those gate nothing this check is about).
294
+ */
295
+ function clauseOfPreHandler(node, file, input, bindings, depth) {
296
+ if (depth > 6)
297
+ return null;
298
+ // `deps.requireAdmin?.('blog.write') ?? (async () => {})` — the guard is the
299
+ // left operand and the fallback is a no-op the harness never takes. Reading
300
+ // the `??` as unreadable is what hid `blog`'s and `cms`'s gates from a first
301
+ // draft of this check.
302
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
303
+ return clauseOfPreHandler(node.left, file, input, bindings, depth + 1);
304
+ }
305
+ if (ts.isCallExpression(node)) {
306
+ const callee = tailName(node.expression);
307
+ if (callee !== null && GUARD_NAMES.has(callee))
308
+ return clauseOfGuardCall(node, file, input);
309
+ return undefined;
310
+ }
311
+ if (ts.isIdentifier(node)) {
312
+ const bound = bindings.get(node.text);
313
+ return bound === undefined ? undefined : clauseOfPreHandler(bound, file, input, bindings, depth + 1);
314
+ }
315
+ if (ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node))
316
+ return null;
317
+ return undefined;
318
+ }
319
+ /** Every `/api/v1/admin/**` route registration under `sources`, with its gate. */
320
+ export function findAdminRoutes(input) {
321
+ const routes = [];
322
+ let unreadablePaths = 0;
323
+ for (const [file, text] of input.sources) {
324
+ if (!text.includes(ADMIN_API_PREFIX))
325
+ continue;
326
+ const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true);
327
+ const bindings = localBindings(sf);
328
+ const moduleId = moduleIdOf(file, input.hostResidentModules);
329
+ const visit = (node) => {
330
+ if (ts.isCallExpression(node) &&
331
+ ts.isPropertyAccessExpression(node.expression) &&
332
+ ROUTE_METHODS.has(node.expression.name.text) &&
333
+ node.arguments.length >= 2) {
334
+ const [pathArgument, optionsArgument] = node.arguments;
335
+ if (pathArgument !== undefined) {
336
+ const looksLikePath = ts.isStringLiteralLike(pathArgument) || ts.isTemplateExpression(pathArgument);
337
+ const path = looksLikePath ? routePathOf(pathArgument, bindings) : null;
338
+ if (looksLikePath && path === null && pathArgument.getText().includes(ADMIN_API_PREFIX)) {
339
+ unreadablePaths += 1;
340
+ }
341
+ if (path !== null && path.startsWith(ADMIN_API_PREFIX)) {
342
+ const gate = gateOf(optionsArgument, file, input, bindings);
343
+ routes.push({
344
+ file,
345
+ line: sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1,
346
+ method: node.expression.name.text,
347
+ path,
348
+ moduleId,
349
+ clauses: gate.clauses,
350
+ gateText: gate.text,
351
+ });
352
+ }
353
+ }
354
+ }
355
+ node.forEachChild(visit);
356
+ };
357
+ sf.forEachChild(visit);
358
+ }
359
+ routes.sort((a, b) => (a.path === b.path ? a.method.localeCompare(b.method) : a.path.localeCompare(b.path)));
360
+ return { routes, unreadablePaths };
361
+ }
362
+ /**
363
+ * The module a source key belongs to, or `null` outside every module tree.
364
+ *
365
+ * The two anchored answers are the application's, on keys relative to its own
366
+ * `src/`. The third is `lib/module-population.ts`' segment reader, which is what
367
+ * attributes a module that has become a workspace package — its key is
368
+ * repository-relative and starts with neither `modules` nor `apps` (feature
369
+ * 080, T040a).
370
+ */
371
+ export function moduleIdOf(file, hostResident = NO_HOST_RESIDENT_MODULES) {
372
+ const segments = file.split('/');
373
+ if (segments[0] === 'modules')
374
+ return segments[1] ?? null;
375
+ // `apps/<deployment>/modules/<id>/…` — an overlay module is an ordinary
376
+ // lifecycle participant and owns its actions the same way (feature 057).
377
+ if (segments[0] === 'apps' && segments[2] === 'modules')
378
+ return segments[3] ?? null;
379
+ return segmentModuleIdOf(file, hostResident);
380
+ }
381
+ const depthOf = (path) => path.split('/').length;
382
+ function shallowest(routes) {
383
+ if (routes.length === 0)
384
+ return routes;
385
+ const min = Math.min(...routes.map((route) => depthOf(route.path)));
386
+ return routes.filter((route) => depthOf(route.path) === min);
387
+ }
388
+ /**
389
+ * The entry route for an action's target, or `null` when no registration
390
+ * corresponds to it at all — which is a defect of its own: a palette entry must
391
+ * point at a real surface.
392
+ */
393
+ export function resolveTarget(action, routes) {
394
+ const creating = action.targetRoute.endsWith('/new');
395
+ const path = creating ? action.targetRoute.slice(0, -'/new'.length) : action.targetRoute;
396
+ const wanted = (route) => creating ? WRITE_METHODS.has(route.method) : route.method === 'get';
397
+ const base = ADMIN_API_PREFIX + path;
398
+ const exact = routes.filter((route) => route.path === base && wanted(route));
399
+ if (exact.length > 0)
400
+ return { level: 'exact', routes: shallowest(exact) };
401
+ const subtree = routes.filter((route) => route.path.startsWith(`${base}/`) && wanted(route));
402
+ if (subtree.length > 0)
403
+ return { level: 'subtree', routes: shallowest(subtree) };
404
+ const owned = routes.filter((route) => route.moduleId === action.moduleId && wanted(route));
405
+ if (owned.length > 0)
406
+ return { level: 'module', routes: shallowest(closestTo(path, owned)) };
407
+ return null;
408
+ }
409
+ /**
410
+ * The module-level candidates whose path names most of the target's segments.
411
+ *
412
+ * At this level the SPA path and the API path have already been established not
413
+ * to correspond, so "shallowest" alone picks by accident: `/platform/modules`
414
+ * would compare against `/api/v1/admin/api-interceptors` as readily as against
415
+ * `/api/v1/admin/modules`, and the two carry different gates. Ranking by shared
416
+ * segment names first keeps the comparison against the route the screen is
417
+ * actually named after, and leaves the ambiguity report for the case where
418
+ * nothing distinguishes the candidates.
419
+ */
420
+ function closestTo(target, routes) {
421
+ const wanted = new Set(target.split('/').filter((segment) => segment.length > 0));
422
+ const score = (route) => route.path
423
+ .slice(ADMIN_API_PREFIX.length)
424
+ .split('/')
425
+ .filter((segment) => wanted.has(segment)).length;
426
+ const best = Math.max(...routes.map(score));
427
+ return routes.filter((route) => score(route) === best);
428
+ }
429
+ /** Whether holding `code` alone passes a gate. Membership in every clause. */
430
+ export function isSufficient(code, clauses) {
431
+ return clauses.every((clause) => clause.includes(code));
432
+ }
433
+ /** A gate's clauses as a stable string, so two candidates can be compared. */
434
+ function gateKey(clauses) {
435
+ return clauses === null ? '<unreadable>' : JSON.stringify(clauses.map((c) => [...c].sort()));
436
+ }
437
+ /** `<moduleId>:<actionId>` — the ledger key, and the identity of a finding. */
438
+ export function keyOf(finding) {
439
+ return `${finding.moduleId}:${finding.actionId}`;
440
+ }
441
+ /**
442
+ * A route's permission clauses, rendered for a message. Exported because the
443
+ * sentence is part of the rule: an author outside this checkout reads the same
444
+ * one this repository's run prints.
445
+ */
446
+ export function renderClauses(clauses) {
447
+ if (clauses.length === 0)
448
+ return '(no code — any authenticated admin)';
449
+ return clauses.map((clause) => (clause.length === 1 ? clause[0] : `any of [${clause.join(', ')}]`)).join(' and ');
450
+ }
451
+ /** Every action whose declared code is not the one its target enforces. */
452
+ export function findDisagreements(input) {
453
+ const findings = [];
454
+ for (const action of input.actions) {
455
+ const base = {
456
+ moduleId: action.moduleId,
457
+ actionId: action.actionId,
458
+ targetRoute: action.targetRoute,
459
+ declared: action.requiredPermission ?? null,
460
+ };
461
+ const resolved = resolveTarget(action, input.routes);
462
+ if (resolved === null) {
463
+ findings.push({
464
+ ...base,
465
+ kind: 'unresolvable',
466
+ enforced: '(no registration)',
467
+ where: `no /api/v1/admin route corresponds to ${action.targetRoute}, and ${action.moduleId} registers none`,
468
+ });
469
+ continue;
470
+ }
471
+ const keys = new Set(resolved.routes.map((route) => gateKey(route.clauses)));
472
+ const [first] = resolved.routes;
473
+ if (first === undefined)
474
+ continue;
475
+ if (keys.size > 1) {
476
+ findings.push({
477
+ ...base,
478
+ kind: 'unresolvable',
479
+ enforced: '(ambiguous)',
480
+ where: `the ${resolved.level}-level candidates for ${action.targetRoute} disagree: ` +
481
+ resolved.routes
482
+ .map((route) => `${route.method.toUpperCase()} ${route.path} → ${renderClauses(route.clauses ?? [])}`)
483
+ .join('; '),
484
+ });
485
+ continue;
486
+ }
487
+ if (first.clauses === null) {
488
+ findings.push({
489
+ ...base,
490
+ kind: 'unresolvable',
491
+ enforced: '(unreadable gate)',
492
+ where: `${first.file}:${first.line} — preHandler \`${first.gateText}\` could not be read`,
493
+ });
494
+ continue;
495
+ }
496
+ const clauses = first.clauses;
497
+ const where = `${first.method.toUpperCase()} ${first.path} (${first.file}:${first.line}, ${resolved.level})`;
498
+ if (action.requiredPermission === undefined) {
499
+ if (clauses.length === 0)
500
+ continue; // Ungated surface, undeclared action — agreed.
501
+ findings.push({ ...base, kind: 'missing', enforced: renderClauses(clauses), where });
502
+ continue;
503
+ }
504
+ if (!isSufficient(action.requiredPermission, clauses)) {
505
+ findings.push({ ...base, kind: 'mismatched', enforced: renderClauses(clauses), where });
506
+ }
507
+ }
508
+ return findings.sort((a, b) => keyOf(a).localeCompare(keyOf(b)));
509
+ }
510
+ export function checkActionRoutePermissions(input, ledger) {
511
+ const findings = findDisagreements(input);
512
+ const keys = new Set(findings.map(keyOf));
513
+ return {
514
+ findings,
515
+ violations: findings.filter((finding) => ledger[keyOf(finding)] === undefined),
516
+ ledgered: findings.filter((finding) => ledger[keyOf(finding)] !== undefined),
517
+ stale: Object.keys(ledger).filter((key) => !keys.has(key)),
518
+ };
519
+ }
520
+ /**
521
+ * The whole analysis, source text in and findings out — the entry a real run
522
+ * takes and the one a red proof has to take with it (issue #130). A fixture
523
+ * handed a ready-made `AdminRoute[]` would prove the comparison and skip the
524
+ * route reading the comparison rests on, which is where every gate shape lives.
525
+ */
526
+ export function analyse(input, ledger) {
527
+ const scan = findAdminRoutes(input);
528
+ return { ...checkActionRoutePermissions({ actions: input.actions, routes: scan.routes }, ledger), scan };
529
+ }
530
+ // ---------------------------------------------------------------------------
531
+ // CLI
532
+ // ---------------------------------------------------------------------------
533
+ /**
534
+ * Every TypeScript source under `dir`, with the rule's own prunes applied.
535
+ *
536
+ * Exported because the population is part of the rule: two hosts computing
537
+ * "which files this check reads" two ways is the shape that lets one of them go
538
+ * half-blind.
539
+ */
540
+ export function collectRouteSources(dir, out = []) {
541
+ if (!existsSync(dir))
542
+ return out;
543
+ for (const name of readdirSync(dir)) {
544
+ const full = join(dir, name);
545
+ if (statSync(full).isDirectory()) {
546
+ if (name === 'node_modules' || name === 'dist')
547
+ continue;
548
+ collectRouteSources(full, out);
549
+ }
550
+ else if (name.endsWith('.ts') && !name.endsWith('.test.ts') && !name.endsWith('.d.ts')) {
551
+ out.push(full);
552
+ }
553
+ }
554
+ return out;
555
+ }
556
+ //# sourceMappingURL=action-route-permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-route-permissions.js","sourceRoot":"","sources":["../../src/rules/action-route-permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /** The log prefix both hosts print under — one grammar, one spelling. */
2
+ export declare const PREFIX = "[bundle-pairing]";
3
+ export type BundlePairingFindingKind = 'missing-language-bundle' | 'empty-bundle' | 'unparseable-bundle' | 'undeclared-bundle-dir';
4
+ /** One registered module, as the generated index and its manifest describe it. */
5
+ export interface ModuleUnderCheck {
6
+ readonly moduleId: string;
7
+ /** The module's own directory — `dirname(manifestPath)`, absolute. */
8
+ readonly directory: string;
9
+ /** `i18n.bundlesDir` from the manifest, or `null` when it declares none. */
10
+ readonly bundlesDir: string | null;
11
+ }
12
+ /**
13
+ * The filesystem, injected.
14
+ *
15
+ * Not for the red proofs — those build a fixture module tree on disk and use the
16
+ * real one, because a fixture that hands in a reader proves the classifier and
17
+ * leaves the walk that feeds it unproven. It exists so a caller measuring a tree
18
+ * it does not own can supply its own reader without this file learning about it.
19
+ */
20
+ export interface BundlePairingFs {
21
+ readonly isDirectory: (path: string) => boolean;
22
+ readonly isFile: (path: string) => boolean;
23
+ readonly readFile: (path: string) => string;
24
+ }
25
+ export declare const nodeBundlePairingFs: BundlePairingFs;
26
+ export interface BundlePairingInput {
27
+ readonly modules: readonly ModuleUnderCheck[];
28
+ /** The platform's shipped languages — `SUPPORTED_LANGUAGES` in a real run. */
29
+ readonly languages: readonly string[];
30
+ readonly fs?: BundlePairingFs;
31
+ }
32
+ export interface BundlePairingFinding {
33
+ readonly kind: BundlePairingFindingKind;
34
+ readonly moduleId: string;
35
+ /** The language it is about, or `null` where the finding is about the module. */
36
+ readonly language: string | null;
37
+ /** The file or directory it names, absolute. */
38
+ readonly path: string;
39
+ /** The sentence the author reads, without the shared remedy. */
40
+ readonly detail: string;
41
+ }
42
+ export interface BundlePairingResult {
43
+ readonly findings: readonly BundlePairingFinding[];
44
+ /** Every bundle file opened — the read line's `files`. */
45
+ readonly filesRead: readonly string[];
46
+ /** Every module classified — the read line's `sites`. */
47
+ readonly classified: readonly string[];
48
+ /** Modules shipping at least one bundle: the ones the predicate binds. */
49
+ readonly shipping: readonly string[];
50
+ /** Modules shipping none: exempt by § 1's conditional, and reported clean. */
51
+ readonly shippingNothing: readonly string[];
52
+ /**
53
+ * How many shipped languages the walk actually probed for — `0` when no module
54
+ * shipped anything at all, which is the vacuous state § 4's fourth condition
55
+ * refuses. It is deliberately *not* "languages a bundle was found in": every
56
+ * module dropping `pl` is a run of findings, not a run that read nothing.
57
+ */
58
+ readonly languagesProbed: number;
59
+ }
60
+ /** The directory names the manifests themselves declare — never a literal. */
61
+ export declare function declaredBundleDirectories(modules: readonly ModuleUnderCheck[]): readonly string[];
62
+ /**
63
+ * The findings, over the modules and languages handed in.
64
+ *
65
+ * Pure but for the injected reader, so a red proof enters where a real run
66
+ * enters: a module tree on disk plus the index's own answer about which modules
67
+ * exist (issue #130). A fixture handing in a per-module classification would
68
+ * prove the reporter and leave the classifier — which is all of the analysis —
69
+ * unproven.
70
+ */
71
+ export declare function checkBundlePairing(input: BundlePairingInput): BundlePairingResult;
72
+ /** The remedy paragraph, one per finding kind. */
73
+ export declare const REMEDIES: Readonly<Record<BundlePairingFindingKind, string>>;
74
+ //# sourceMappingURL=bundle-pairing.d.ts.map