@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,594 @@
1
+ /**
2
+ * CI check — **a module's background consumers reach the module's own seam**:
3
+ * an EventBus subscription through `ctx.subscribe` and never a bare
4
+ * `eventBus.on` (issue #107), a BullMQ queue consumer through `ctx.worker` /
5
+ * `defineModuleWorker` and never a `Worker` nobody registered. Constitution
6
+ * XVII, in both halves.
7
+ *
8
+ * The second signal is here rather than in a script of its own because the
9
+ * paragraph four lines below is the one that made it look unnecessary — *"routes
10
+ * have the `ctx.routes` seam; workers have `defineModuleWorker`; subscriptions
11
+ * had nothing"* — and it was wrong about workers in exactly the way it says
12
+ * subscriptions were wrong. `pwa` constructed its push-delivery `Worker` and
13
+ * dropped the value on the floor: in no per-module registry, so
14
+ * `pauseWorkersFor('pwa')` reached nothing and an operator who switched `pwa`
15
+ * off went on having push notifications delivered to their customers' devices.
16
+ * One rule, one population (a module's own sources), one ledger.
17
+ *
18
+
19
+ * `ctx.subscribe` wraps the handler in `subscribeForModule`, which is what makes
20
+ * the module's effective state decide whether the handler runs at all. A
21
+ * registration written as `eventBus.on(...)` keeps its handler attached for the
22
+ * process lifetime, so a module an operator switched off goes on reacting to
23
+ * every event the platform emits.
24
+ *
25
+ * That is worse than a route that keeps answering, because a subscriber
26
+ * **writes**: the sweep that produced this check found twenty-two such
27
+ * registrations across nine modules; **ten** wrote to the platform's own
28
+ * database — an invoice issued and e-mailed, a quote request flipped to
29
+ * Completed, a push message row created and delivered to a device, a shopping
30
+ * list created, a threshold row mirrored, a feed's and a PIM import's next-run
31
+ * stamp written back — and **twenty-one of the twenty-two** mutated something,
32
+ * the exception being `catalog`'s cache flush at the storefront.
33
+ *
34
+ * Routes have `check-kernel-boundary` and the `ctx.routes` seam; workers have
35
+ * `defineModuleWorker`; subscriptions had nothing, which is why twenty-two
36
+ * accumulated while every one of those modules' conversion tasks read done.
37
+ *
38
+ * ## What counts as a subscription
39
+ *
40
+ * A call `<receiver>.on(<event>, <handler>)` in a file that belongs to a module
41
+ * — core under `src/modules`, overlay under `src/apps` — where the receiver
42
+ * reads as an event bus. Three
43
+ * signals, because the receiver is spelled several ways and the check follows
44
+ * the shape rather than one literal:
45
+ *
46
+ * 1. the receiver's trailing identifier is bus-shaped — `eventBus`, `bus`,
47
+ * `events`, `options.eventBus`, `this.deps.eventBus`;
48
+ * 2. the receiver is a cast around one — `(options.eventBus as CategoryEventBus).on`;
49
+ * 3. the first argument is a **domain event name** (`a.b`, `a.b.v1`), which is
50
+ * what distinguishes a bus from a BullMQ worker (`'completed'`), an ioredis
51
+ * subscriber (`'message'`) and a Node stream (`'data'`).
52
+ *
53
+ * The kernel is deliberately out of scope. `src/kernel/settings` and
54
+ * `src/kernel/sales-channels` each attach a cache invalidator with a bare
55
+ * `eventBus.on`, and that is correct: the kernel composes before any module and
56
+ * has no effective state to gate on — there is no operator switch that makes the
57
+ * settings cache stop invalidating.
58
+ *
59
+ * ## What counts as a queue consumer
60
+ *
61
+ * Two findings, because the tree spells the same thing two ways and only one of
62
+ * them names `Worker` at the site that matters:
63
+ *
64
+ * 1. **`ungated-construction`** — `new Worker(...)` in a module's own sources,
65
+ * where `Worker` is the binding the file imported from `bullmq`, and the
66
+ * value neither goes into a seam call nor is `return`ed. Returning it is
67
+ * what a *factory* does, and a factory is not the registration: ten of the
68
+ * fifteen constructions in the tree sit in a `services/queues/*.ts` whose
69
+ * caller wraps them.
70
+ * 2. **`ungated-registration`** — a call to one of those factories whose value
71
+ * goes nowhere. This is the one `pwa` failed, and the one a check keyed on
72
+ * `new Worker(` cannot see at all.
73
+ *
74
+ * "Goes nowhere" is four questions, and each was a real shape in the tree when
75
+ * this landed: it is not inside a seam call; it is not `return`ed; it is not
76
+ * bound to a name this file later hands to a seam; and it is not bound to a name
77
+ * this function **returns** — which is `pwa`'s repaired shape
78
+ * (`const workers = […]; return { plugin, handle, workers }`) and `ksef`'s
79
+ * (`worker = createKsefSubmitWorker(…)`, returned as `workers: worker ? [worker] : []`).
80
+ * The last one is what T051's conversion made the common case: a module's
81
+ * `plugin.ts` collects its workers and its `backend.ts` hands each to
82
+ * `ctx.worker`, so the value crosses a file boundary. The analysis stops at the
83
+ * return — it does not follow the value into the caller — which is stated here
84
+ * rather than pretended away. What it still catches is the drop on the floor.
85
+ *
86
+ * The **seam** is likewise not two literals: `catalog` and `newsletter` take a
87
+ * `registerWorker(worker, options)` callback from their own `backend.ts` whose
88
+ * body is `ctx.worker(worker, options)`, so the forwarder names are derived from
89
+ * the bodies that call the seam, exactly as the factory names are derived from
90
+ * what they return. Neither set is written down; the next module will name both
91
+ * something else.
92
+ *
93
+ * The factory set is **derived**, never a naming convention: pass one walks the
94
+ * whole tree for functions that return a BullMQ `Worker` and records their
95
+ * names, so `createPushDeliveryWorker` is recognised because of what it returns
96
+ * and a `makeThing` that returns one would be too. A convention (`create*Worker`)
97
+ * would have had issue #244's defect — a population defined by the presence of
98
+ * the very habit the rule is about.
99
+ *
100
+ * What it cannot see, stated here rather than discovered later: a worker handed
101
+ * across files to a caller that forgets the seam (the analysis stops at the
102
+ * return), a `Worker` subclass, a construction behind a computed callee, and a
103
+ * `defineModuleWorker` called with the **wrong module id** — that last one is a
104
+ * different rule and `pauseWorkersFor` would find the worker under a name no
105
+ * manifest has. The seam itself is recognised by callee name — `defineModuleWorker`,
106
+ * or any `.worker(…)` — which over-approximates in the direction of "gated": a
107
+ * module that had some *other* collaborator with a `worker(…)` method could hide
108
+ * a bypass inside its arguments. There is no such method in the tree, and
109
+ * narrowing the receiver to `ctx` would refuse the next author who names their
110
+ * `ModuleContext` something else.
111
+ *
112
+ * ## One analysis, two hosts
113
+ *
114
+ * This file is the analysis. `backend/scripts/check-subscribe-seam.ts` hosts it
115
+ * over this repository's source roots; `endora check` hosts it over one module
116
+ * package (`specs/101-endora-check/contracts/package-scope-layout.md` §6).
117
+ *
118
+ * The worker half's exit-2 floor — *no BullMQ worker site at all* — is a
119
+ * statement about a **repository** whose tree is known to hold queue consumers.
120
+ * A single package holding none is the ordinary case, so the package-scope host
121
+ * declares that floor unevaluated on the rule's own line rather than refusing;
122
+ * see `contracts/exit-reduction.md` § 1's partial verdict.
123
+ */
124
+ import { existsSync, readdirSync, statSync } from 'node:fs';
125
+ import { join } from 'node:path';
126
+ import ts from 'typescript';
127
+ import { NO_HOST_RESIDENT_MODULES, } from '../lib/module-population.js';
128
+ // `moduleOf` — attribute a file to a module over every root a module can live
129
+ // in — has its one CLI-side home in the relocated container-imports rule. The
130
+ // two copies still standing in `backend/scripts/` (this check's former import
131
+ // from `check-port-dependencies.ts`, and `check-container-imports.ts`' own) are
132
+ // pre-existing residue of the estate's growth, not something this relocation
133
+ // introduced; a third copy here would be.
134
+ import { moduleOf } from './container-imports.js';
135
+ /** An event name the payload of which is a domain event: `a.b`, `a.b.v1`. */
136
+ const DOMAIN_EVENT = /^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+$/;
137
+ /** A receiver whose trailing name says "event bus" whatever it is typed as. */
138
+ const BUS_RECEIVER = /^(event_?bus|bus|events|eventEmitter)$/i;
139
+ /** What the key carries when the subscription's event name is not a literal. */
140
+ const DYNAMIC = '<dynamic>';
141
+ /**
142
+ * Bare subscriptions that may stay bare, with the reason and the question that
143
+ * would retire the entry.
144
+ *
145
+ * Keyed `<path under src/>:<event>` rather than by line, so moving code inside a
146
+ * file does not invalidate an entry and re-opening the hole does not silently
147
+ * inherit one. **Two-way**, in the idiom of `PORT_CATCHES_TO_DRAIN` and
148
+ * `WIRING_RESOLUTIONS_TO_DRAIN`: an unledgered bare subscription fails the
149
+ * build, and a ledger entry that no longer describes one fails it too.
150
+ *
151
+ * It is empty, and that is the point: every module subscription in the tree goes
152
+ * through `ctx.subscribe`. An entry here is a module that reacts to events while
153
+ * an operator believes it is switched off, so a reason has to say why that is
154
+ * the least-wrong behaviour rather than that nobody has moved it yet.
155
+ */
156
+ export const BARE_SUBSCRIPTIONS_TO_DRAIN = {};
157
+ /**
158
+ * Queue consumers that may stay outside the seam, with the reason and the
159
+ * question that would retire the entry.
160
+ *
161
+ * Keyed `<path under src/>:<spelling>`, two-way, and empty for the same reason
162
+ * the subscription ledger is: a worker outside `ctx.worker` is a module doing
163
+ * work while an operator believes it is switched off, and there is no per-worker
164
+ * remedy — the registry is the only thing `pauseWorkersFor` and the presence
165
+ * reconcile can reach. An entry has to say why *that* is the least-wrong
166
+ * behaviour.
167
+ */
168
+ export const WORKERS_OUTSIDE_THE_SEAM = {};
169
+ /** The seam a module's queue consumer has to reach, in the two spellings. */
170
+ const WORKER_SEAM_CALLEES = new Set(['defineModuleWorker', 'worker']);
171
+ /**
172
+ * Every file the seam rule judges, under `roots`.
173
+ *
174
+ * Exported because both hosts walk: the repository's source roots and one
175
+ * package's. A second copy would be two definitions of one population.
176
+ */
177
+ export function collectSeamFiles(roots) {
178
+ return roots.flatMap((root) => walk(root));
179
+ }
180
+ function walk(dir, out = []) {
181
+ if (!existsSync(dir))
182
+ return out;
183
+ for (const name of readdirSync(dir)) {
184
+ const full = join(dir, name);
185
+ if (statSync(full).isDirectory()) {
186
+ if (name === 'node_modules' || name === 'dist')
187
+ continue;
188
+ walk(full, out);
189
+ }
190
+ else if (name.endsWith('.ts') && !name.endsWith('.test.ts') && !name.endsWith('.d.ts')) {
191
+ out.push(full);
192
+ }
193
+ }
194
+ return out;
195
+ }
196
+ /** `<file>:<event>` — the ledger key, and the identity of a site. */
197
+ export function keyOf(found) {
198
+ return `${found.file}:${found.event}`;
199
+ }
200
+ /** The trailing identifier of a receiver: `this.deps.eventBus` → `eventBus`. */
201
+ function tailName(node) {
202
+ if (ts.isIdentifier(node))
203
+ return node.text;
204
+ if (ts.isPropertyAccessExpression(node))
205
+ return node.name.text;
206
+ if (ts.isAsExpression(node) ||
207
+ ts.isNonNullExpression(node) ||
208
+ ts.isParenthesizedExpression(node) ||
209
+ ts.isTypeAssertionExpression(node)) {
210
+ return tailName(node.expression);
211
+ }
212
+ return null;
213
+ }
214
+ /** The string an argument denotes, through any number of casts. */
215
+ function stringLiteralOf(node) {
216
+ if (ts.isStringLiteralLike(node))
217
+ return node.text;
218
+ if (ts.isAsExpression(node) ||
219
+ ts.isNonNullExpression(node) ||
220
+ ts.isParenthesizedExpression(node) ||
221
+ ts.isTypeAssertionExpression(node)) {
222
+ return stringLiteralOf(node.expression);
223
+ }
224
+ return null;
225
+ }
226
+ /** Every `<bus>.on(<event>, <handler>)` in a module's own sources. */
227
+ export function findBareSubscriptions(input) {
228
+ const found = [];
229
+ const hostResident = input.hostResidentModules ?? NO_HOST_RESIDENT_MODULES;
230
+ for (const [file, text] of input.sources) {
231
+ const moduleId = moduleOf(`/src/${file}`, hostResident);
232
+ // Only a module has an effective state to gate on. A file outside one —
233
+ // the kernel, `http/`, `db/`, a composition root — is not this rule's
234
+ // business.
235
+ if (moduleId === null)
236
+ continue;
237
+ const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true);
238
+ const visit = (node) => {
239
+ if (ts.isCallExpression(node) &&
240
+ ts.isPropertyAccessExpression(node.expression) &&
241
+ node.expression.name.text === 'on' &&
242
+ node.arguments.length >= 2) {
243
+ const receiver = tailName(node.expression.expression);
244
+ const [nameArgument] = node.arguments;
245
+ // `'order.status_changed.v1' as never` is the spelling `pwa` used to
246
+ // satisfy an untyped bus, so the cast is unwrapped before the literal
247
+ // is read — otherwise the ledger key would say `<dynamic>` for an event
248
+ // written out in full.
249
+ const literal = nameArgument === undefined ? null : stringLiteralOf(nameArgument);
250
+ const looksLikeBus = receiver !== null && BUS_RECEIVER.test(receiver);
251
+ const looksLikeDomainEvent = literal !== null && DOMAIN_EVENT.test(literal);
252
+ if (looksLikeBus || looksLikeDomainEvent) {
253
+ found.push({
254
+ file,
255
+ line: sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1,
256
+ moduleId,
257
+ event: literal ?? DYNAMIC,
258
+ receiver: receiver ?? '(expression)',
259
+ });
260
+ }
261
+ }
262
+ node.forEachChild(visit);
263
+ };
264
+ sf.forEachChild(visit);
265
+ }
266
+ found.sort((a, b) => (a.file === b.file ? a.line - b.line : a.file.localeCompare(b.file)));
267
+ return found;
268
+ }
269
+ /** `<file>:<spelling>` — the ledger key, and the identity of a site. */
270
+ export function workerKeyOf(site) {
271
+ return `${site.file}:${site.spelling}`;
272
+ }
273
+ /** The local name a file bound BullMQ's `Worker` to, if it imported one. */
274
+ function bullmqWorkerBinding(sf) {
275
+ let binding = null;
276
+ for (const statement of sf.statements) {
277
+ if (!ts.isImportDeclaration(statement))
278
+ continue;
279
+ if (stringLiteralOf(statement.moduleSpecifier) !== 'bullmq')
280
+ continue;
281
+ const clause = statement.importClause;
282
+ const named = clause?.namedBindings;
283
+ if (!named || !ts.isNamedImports(named))
284
+ continue;
285
+ for (const element of named.elements) {
286
+ // `import { Worker }` and `import { Worker as BullWorker }` alike: what
287
+ // matters is the *imported* name, and the local one is what the site says.
288
+ if ((element.propertyName ?? element.name).text === 'Worker') {
289
+ binding = element.name.text;
290
+ }
291
+ }
292
+ }
293
+ return binding;
294
+ }
295
+ /** The callee's own name, whichever of the two shapes it is written in. */
296
+ function calleeName(call) {
297
+ const callee = call.expression;
298
+ if (ts.isIdentifier(callee))
299
+ return callee.text;
300
+ if (ts.isPropertyAccessExpression(callee))
301
+ return callee.name.text;
302
+ return null;
303
+ }
304
+ /** True when `node` sits inside the arguments of a call to a seam or a forwarder. */
305
+ function insideSeamCall(node, seams) {
306
+ for (let cursor = node.parent; cursor; cursor = cursor.parent) {
307
+ if (!ts.isCallExpression(cursor))
308
+ continue;
309
+ const name = calleeName(cursor);
310
+ if (name !== null && seams.has(name))
311
+ return true;
312
+ }
313
+ return false;
314
+ }
315
+ /** True when `node`'s value is itself returned — a factory hands it to its caller. */
316
+ function isHandedToCaller(node) {
317
+ for (let cursor = node.parent; cursor; cursor = cursor.parent) {
318
+ if (ts.isReturnStatement(cursor))
319
+ return true;
320
+ if (ts.isArrowFunction(cursor) && cursor.body === node)
321
+ return true;
322
+ if (ts.isFunctionLike(cursor))
323
+ return false;
324
+ }
325
+ return false;
326
+ }
327
+ /**
328
+ * The name a call's value lands in, through the wrappers that do not change
329
+ * whose value it is: an array or object literal, a conditional, a cast, a
330
+ * `push` onto a collection.
331
+ *
332
+ * `const workers = runWorkers ? [createXWorker(…)] : []` and
333
+ * `worker = createXWorker(…)` both answer with the collection's name, which is
334
+ * what the two rules below then ask about.
335
+ */
336
+ function boundCollectionName(node) {
337
+ let current = node;
338
+ for (let cursor = node.parent; cursor; cursor = cursor.parent) {
339
+ if (ts.isVariableDeclaration(cursor) && ts.isIdentifier(cursor.name))
340
+ return cursor.name.text;
341
+ if (ts.isBinaryExpression(cursor) &&
342
+ cursor.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
343
+ ts.isIdentifier(cursor.left)) {
344
+ return cursor.left.text;
345
+ }
346
+ if (ts.isCallExpression(cursor) && calleeName(cursor) === 'push') {
347
+ const receiver = cursor.expression;
348
+ if (ts.isPropertyAccessExpression(receiver) && ts.isIdentifier(receiver.expression)) {
349
+ return receiver.expression.text;
350
+ }
351
+ return null;
352
+ }
353
+ const transparent = ts.isArrayLiteralExpression(cursor) ||
354
+ ts.isObjectLiteralExpression(cursor) ||
355
+ ts.isPropertyAssignment(cursor) ||
356
+ ts.isShorthandPropertyAssignment(cursor) ||
357
+ ts.isConditionalExpression(cursor) ||
358
+ ts.isParenthesizedExpression(cursor) ||
359
+ ts.isAsExpression(cursor) ||
360
+ ts.isNonNullExpression(cursor);
361
+ if (!transparent)
362
+ return null;
363
+ current = cursor;
364
+ }
365
+ void current;
366
+ return null;
367
+ }
368
+ /** Every identifier mentioned in a `return` of the function that encloses `node`. */
369
+ function namesReturnedFromEnclosingFunction(node) {
370
+ let fn;
371
+ for (let cursor = node.parent; cursor; cursor = cursor.parent) {
372
+ if (ts.isFunctionLike(cursor)) {
373
+ fn = cursor;
374
+ break;
375
+ }
376
+ }
377
+ const names = new Set();
378
+ if (!fn)
379
+ return names;
380
+ const collect = (n) => {
381
+ if (ts.isIdentifier(n))
382
+ names.add(n.text);
383
+ if (ts.isShorthandPropertyAssignment(n))
384
+ names.add(n.name.text);
385
+ n.forEachChild(collect);
386
+ };
387
+ const visit = (n) => {
388
+ if (ts.isFunctionLike(n) && n !== fn)
389
+ return;
390
+ if (ts.isReturnStatement(n) && n.expression)
391
+ collect(n.expression);
392
+ n.forEachChild(visit);
393
+ };
394
+ const body = fn.body;
395
+ if (body && !ts.isBlock(body)) {
396
+ collect(body);
397
+ return names;
398
+ }
399
+ if (body)
400
+ body.forEachChild(visit);
401
+ return names;
402
+ }
403
+ /** The nearest enclosing function's name, for the factory index. */
404
+ function enclosingFunctionName(node) {
405
+ for (let cursor = node.parent; cursor; cursor = cursor.parent) {
406
+ if (ts.isFunctionDeclaration(cursor) || ts.isMethodDeclaration(cursor)) {
407
+ return cursor.name && ts.isIdentifier(cursor.name) ? cursor.name.text : null;
408
+ }
409
+ if (ts.isFunctionExpression(cursor) || ts.isArrowFunction(cursor)) {
410
+ const parent = cursor.parent;
411
+ if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name))
412
+ return parent.name.text;
413
+ return null;
414
+ }
415
+ }
416
+ return null;
417
+ }
418
+ /**
419
+ * Pass one — every function in the walked tree that returns a BullMQ `Worker`.
420
+ *
421
+ * Derived rather than conventional (see the header): the second finding needs to
422
+ * know that `createPushDeliveryWorker(...)` **is** a worker, and the only honest
423
+ * source for that is what the function returns.
424
+ */
425
+ export function findWorkerFactories(input) {
426
+ const names = new Set();
427
+ for (const [file, text] of input.sources) {
428
+ const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true);
429
+ const binding = bullmqWorkerBinding(sf);
430
+ if (binding === null)
431
+ continue;
432
+ const visit = (node) => {
433
+ if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === binding) {
434
+ if (isHandedToCaller(node)) {
435
+ const name = enclosingFunctionName(node);
436
+ if (name !== null)
437
+ names.add(name);
438
+ }
439
+ }
440
+ node.forEachChild(visit);
441
+ };
442
+ sf.forEachChild(visit);
443
+ }
444
+ return names;
445
+ }
446
+ /**
447
+ * Pass one-and-a-half — the names that **forward** to the seam.
448
+ *
449
+ * `catalog` and `newsletter` take a `registerWorker(worker, options)` callback
450
+ * from their own `backend.ts`, whose body is `ctx.worker(worker, options)`. That
451
+ * is the seam reached one hop away, and a rule that knew only the two literal
452
+ * spellings would report both modules as bypassing it. The set is **derived**
453
+ * from the bodies rather than written down, for the reason the factory set is:
454
+ * the next module will name its callback something else.
455
+ */
456
+ export function findSeamForwarders(input) {
457
+ const names = new Set();
458
+ for (const [file, text] of input.sources) {
459
+ const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true);
460
+ const visit = (node) => {
461
+ if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name)) {
462
+ const body = node.initializer;
463
+ if ((ts.isArrowFunction(body) || ts.isFunctionExpression(body)) && callsSeam(body)) {
464
+ names.add(node.name.text);
465
+ }
466
+ }
467
+ node.forEachChild(visit);
468
+ };
469
+ sf.forEachChild(visit);
470
+ }
471
+ return names;
472
+ }
473
+ /** Does this function body call one of the two literal seam spellings? */
474
+ function callsSeam(fn) {
475
+ let found = false;
476
+ const visit = (node) => {
477
+ if (found)
478
+ return;
479
+ if (ts.isCallExpression(node)) {
480
+ const name = calleeName(node);
481
+ if (name !== null && WORKER_SEAM_CALLEES.has(name))
482
+ found = true;
483
+ }
484
+ node.forEachChild(visit);
485
+ };
486
+ fn.forEachChild(visit);
487
+ return found;
488
+ }
489
+ /**
490
+ * Pass two — every queue-consumer site in a module's own sources, gated or not.
491
+ *
492
+ * The whole population is returned, not only the findings: the caller reports
493
+ * how many it read, and a vocabulary that resolved to nothing is exit 2 rather
494
+ * than a clean bill of health (issue #113).
495
+ */
496
+ export function findWorkerSites(input, factories, forwarders = new Set()) {
497
+ const sites = [];
498
+ const seams = new Set([...WORKER_SEAM_CALLEES, ...forwarders]);
499
+ const hostResident = input.hostResidentModules ?? NO_HOST_RESIDENT_MODULES;
500
+ for (const [file, text] of input.sources) {
501
+ const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true);
502
+ const binding = bullmqWorkerBinding(sf);
503
+ const lineOf = (node) => sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
504
+ // One file-local pass first: which names does this file hand to a seam? A
505
+ // module that writes `const w = createXWorker(…)` and registers `w` two
506
+ // lines down is right, and the check has to be able to say so.
507
+ const registeredBindings = new Set();
508
+ const collectRegistered = (node) => {
509
+ if (ts.isCallExpression(node)) {
510
+ const name = calleeName(node);
511
+ if (name !== null && seams.has(name)) {
512
+ for (const argument of node.arguments) {
513
+ if (ts.isIdentifier(argument))
514
+ registeredBindings.add(argument.text);
515
+ }
516
+ }
517
+ }
518
+ node.forEachChild(collectRegistered);
519
+ };
520
+ sf.forEachChild(collectRegistered);
521
+ /**
522
+ * Gated when the value reaches the seam here, or leaves this function for a
523
+ * caller that will. Since the T051 conversion the second is the common
524
+ * shape: a module's `plugin.ts` collects its workers and its `backend.ts`
525
+ * hands each to `ctx.worker`, so the value crosses a file boundary and this
526
+ * analysis stops at the return — stated in the header rather than pretended
527
+ * away. What it still catches is the drop on the floor, which is the defect.
528
+ */
529
+ const isGated = (node) => {
530
+ if (insideSeamCall(node, seams) || isHandedToCaller(node))
531
+ return true;
532
+ const bound = boundCollectionName(node);
533
+ if (bound === null)
534
+ return false;
535
+ return registeredBindings.has(bound) || namesReturnedFromEnclosingFunction(node).has(bound);
536
+ };
537
+ const visit = (node) => {
538
+ if (binding !== null &&
539
+ ts.isNewExpression(node) &&
540
+ ts.isIdentifier(node.expression) &&
541
+ node.expression.text === binding) {
542
+ sites.push({
543
+ file,
544
+ line: lineOf(node),
545
+ moduleId: moduleOf(`/src/${file}`, hostResident),
546
+ kind: 'construction',
547
+ spelling: `new ${binding}`,
548
+ gated: isGated(node),
549
+ });
550
+ }
551
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
552
+ const callee = node.expression.text;
553
+ if (factories.has(callee)) {
554
+ sites.push({
555
+ file,
556
+ line: lineOf(node),
557
+ moduleId: moduleOf(`/src/${file}`, hostResident),
558
+ kind: 'registration',
559
+ spelling: callee,
560
+ gated: isGated(node),
561
+ });
562
+ }
563
+ }
564
+ node.forEachChild(visit);
565
+ };
566
+ sf.forEachChild(visit);
567
+ }
568
+ sites.sort((a, b) => (a.file === b.file ? a.line - b.line : a.file.localeCompare(b.file)));
569
+ return sites;
570
+ }
571
+ export function checkWorkerSeam(input, ledger = WORKERS_OUTSIDE_THE_SEAM) {
572
+ const sites = findWorkerSites(input, findWorkerFactories(input), findSeamForwarders(input));
573
+ // Only a module has an effective state to gate on; a factory in a shared
574
+ // directory is judged where it is called.
575
+ const ungated = sites.filter((site) => !site.gated && site.moduleId !== null);
576
+ const keys = new Set(ungated.map(workerKeyOf));
577
+ return {
578
+ sites,
579
+ violations: ungated.filter((site) => ledger[workerKeyOf(site)] === undefined),
580
+ ledgered: ungated.filter((site) => ledger[workerKeyOf(site)] !== undefined),
581
+ stale: Object.keys(ledger).filter((key) => !keys.has(key)),
582
+ };
583
+ }
584
+ export function checkSubscribeSeam(input, ledger = BARE_SUBSCRIPTIONS_TO_DRAIN) {
585
+ const all = findBareSubscriptions(input);
586
+ const keys = new Set(all.map(keyOf));
587
+ return {
588
+ total: all.length,
589
+ violations: all.filter((entry) => ledger[keyOf(entry)] === undefined),
590
+ ledgered: all.filter((entry) => ledger[keyOf(entry)] !== undefined),
591
+ stale: Object.keys(ledger).filter((key) => !keys.has(key)),
592
+ };
593
+ }
594
+ //# sourceMappingURL=subscribe-seam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe-seam.js","sourceRoot":"","sources":["../../src/rules/subscribe-seam.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /** Which lexical scope guarantees a transaction around the finding. */
2
+ export type TransactionScope = 'transactional-callback' | 'command-run';
3
+ /** Why the statement cannot see the transaction it is written inside. */
4
+ export type EscapeShape = 'knex-instance' | 'connection-execute';
5
+ export interface TransactionEscape {
6
+ /** Path under `src/`, POSIX separators. */
7
+ readonly file: string;
8
+ readonly line: number;
9
+ readonly scope: TransactionScope;
10
+ readonly shape: EscapeShape;
11
+ /** `write` when the statement on that line moves rows, per `lib/sql-tables.ts`. */
12
+ readonly direction: 'read' | 'write' | 'unknown';
13
+ /** The statement head, or the expression, for the message and the ledger key. */
14
+ readonly statement: string;
15
+ }
16
+ /** `<file>#<shape>#<statement>` — the ledger key, and the identity of a site. */
17
+ export declare function keyOf(found: TransactionEscape): string;
18
+ export interface TransactionContextInput {
19
+ /** Every source under `src/`, keyed by path relative to `src/`. */
20
+ readonly sources: ReadonlyMap<string, string>;
21
+ }
22
+ /**
23
+ * Every TypeScript source under `dir`, with the rule's own prunes applied.
24
+ *
25
+ * Exported because the population is part of the rule, not part of a host: two
26
+ * hosts computing "which files this check reads" two ways is the shape that
27
+ * lets one of them go half-blind.
28
+ */
29
+ export declare function collectTransactionSources(dir: string, out?: string[]): string[];
30
+ /** Every statement written inside a transaction that does not run inside it. */
31
+ export declare function findTransactionEscapes(input: TransactionContextInput): TransactionEscape[];
32
+ export interface CheckResult {
33
+ readonly total: number;
34
+ readonly violations: readonly TransactionEscape[];
35
+ readonly ledgered: readonly TransactionEscape[];
36
+ /** Ledger keys that no longer describe an escape — the staleness half. */
37
+ readonly stale: readonly string[];
38
+ }
39
+ export declare function checkTransactionContext(input: TransactionContextInput, ledger: Readonly<Record<string, string>>): CheckResult;
40
+ //# sourceMappingURL=transaction-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction-context.d.ts","sourceRoot":"","sources":["../../src/rules/transaction-context.ts"],"names":[],"mappings":"AA6EA,uEAAuE;AACvE,MAAM,MAAM,gBAAgB,GAAG,wBAAwB,GAAG,aAAa,CAAC;AAExE,yEAAyE;AACzE,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACjD,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,iFAAiF;AACjF,wBAAgB,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAEtD;AAED,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAYnF;AAgHD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,uBAAuB,GAAG,iBAAiB,EAAE,CAkF1F;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACvC,WAAW,CASb"}