hammerkit 1.5.1 → 1.6.0-alpha.2

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 (480) hide show
  1. package/.agents/FEEDBACK.md +74 -0
  2. package/.agents/skills/before-commit/SKILL.md +101 -0
  3. package/.agents/skills/do-the-work/SKILL.md +64 -0
  4. package/.agents/skills/fix-ci/SKILL.md +98 -0
  5. package/.agents/skills/speckit-git-commit/SKILL.md +53 -0
  6. package/.agents/skills/speckit-git-feature/SKILL.md +72 -0
  7. package/.agents/skills/speckit-git-initialize/SKILL.md +54 -0
  8. package/.agents/skills/speckit-git-remote/SKILL.md +50 -0
  9. package/.agents/skills/speckit-git-validate/SKILL.md +54 -0
  10. package/.gitbook.yaml +5 -0
  11. package/.specify/extensions/.registry +37 -0
  12. package/.specify/extensions/git/README.md +100 -0
  13. package/.specify/extensions/git/commands/speckit.git.commit.md +48 -0
  14. package/.specify/extensions/git/commands/speckit.git.feature.md +67 -0
  15. package/.specify/extensions/git/commands/speckit.git.initialize.md +49 -0
  16. package/.specify/extensions/git/commands/speckit.git.remote.md +45 -0
  17. package/.specify/extensions/git/commands/speckit.git.validate.md +49 -0
  18. package/.specify/extensions/git/config-template.yml +62 -0
  19. package/.specify/extensions/git/extension.yml +140 -0
  20. package/.specify/extensions/git/git-config.yml +62 -0
  21. package/.specify/extensions.yml +149 -0
  22. package/.specify/feature.json +3 -0
  23. package/.specify/init-options.json +10 -0
  24. package/.specify/integration.json +15 -0
  25. package/.specify/integrations/claude.manifest.json +16 -0
  26. package/.specify/integrations/speckit.manifest.json +17 -0
  27. package/.specify/memory/constitution.md +162 -0
  28. package/.specify/templates/checklist-template.md +40 -0
  29. package/.specify/templates/constitution-template.md +50 -0
  30. package/.specify/templates/plan-template.md +113 -0
  31. package/.specify/templates/spec-template.md +131 -0
  32. package/.specify/templates/tasks-template.md +252 -0
  33. package/.specify/workflows/speckit/workflow.yml +77 -0
  34. package/.specify/workflows/workflow-registry.json +13 -0
  35. package/AGENTS.md +94 -0
  36. package/Dockerfile +3 -3
  37. package/FOLLOWUPS.md +34 -0
  38. package/README.md +9 -7
  39. package/SUMMARY.md +30 -5
  40. package/VALUES.md +53 -0
  41. package/build.schema.json +542 -408
  42. package/dist/cache/auto-pull.spec.js +123 -0
  43. package/dist/cache/backends/local-cache-backend.js +56 -0
  44. package/dist/cache/backends/local-cache-backend.spec.js +72 -0
  45. package/dist/cache/backends/s3-cache-backend.js +124 -0
  46. package/dist/cache/backends/s3-cache-backend.spec.js +118 -0
  47. package/dist/cache/cache-backend-registry.js +21 -0
  48. package/dist/cache/cache-backend-registry.spec.js +22 -0
  49. package/dist/cache/cache-backend.js +3 -0
  50. package/dist/cache/resolve-cache.js +60 -0
  51. package/dist/cache/resolve-cache.spec.js +52 -0
  52. package/dist/cli.js +112 -82
  53. package/dist/cli.spec.js +20 -2
  54. package/dist/console/get-logger.spec.js +23 -0
  55. package/dist/docker/get-default-platform.spec.js +29 -0
  56. package/dist/docker/longest-common-prefix.spec.js +26 -0
  57. package/dist/docker/package.js +283 -0
  58. package/dist/docker/package.spec.js +145 -0
  59. package/dist/docker/pull.js +4 -4
  60. package/dist/docker/remove-container.spec.js +32 -0
  61. package/dist/docker/stream.js +3 -3
  62. package/dist/docker/using-container.js +29 -11
  63. package/dist/docker/using-container.spec.js +90 -0
  64. package/dist/environment/merge-environment-variables.js +21 -0
  65. package/dist/environment/merge-environment-variables.spec.js +24 -0
  66. package/dist/environment/replace-env-variables.js +43 -10
  67. package/dist/environment/replace-env-variables.spec.js +47 -0
  68. package/dist/executer/abort.spec.js +18 -0
  69. package/dist/executer/await-completed-dependencies.js +56 -0
  70. package/dist/executer/cache-metadata.js +11 -0
  71. package/dist/executer/check-readiness.js +1 -1
  72. package/dist/{planner/work-node-port.js → executer/container-bind.js} +1 -1
  73. package/dist/executer/docker-service.js +110 -86
  74. package/dist/executer/docker-task.js +132 -0
  75. package/dist/executer/environment-mock.js +3 -4
  76. package/dist/executer/environment-mock.spec.js +22 -0
  77. package/dist/executer/event-cache.js +60 -127
  78. package/dist/executer/execute-command.js +4 -3
  79. package/dist/executer/execute-docker.js +32 -14
  80. package/dist/executer/execute-work-service.js +61 -0
  81. package/dist/executer/execute-work-task.js +107 -0
  82. package/dist/executer/execute-work-tree.js +27 -0
  83. package/dist/executer/execute.spec.js +14 -10
  84. package/dist/executer/execution-steps.js +47 -31
  85. package/dist/executer/get-container-binds.js +19 -0
  86. package/dist/executer/get-docker-executor.js +12 -12
  87. package/dist/executer/get-scheduler-down-result.js +12 -0
  88. package/dist/executer/get-scheduler-execute-result.js +28 -0
  89. package/dist/executer/get-scheduler-up-result.js +12 -0
  90. package/dist/executer/get-service-containers.js +14 -0
  91. package/dist/executer/get-service-containers.spec.js +59 -0
  92. package/dist/executer/get-service-env-hints.js +35 -0
  93. package/dist/executer/get-service-env-hints.spec.js +65 -0
  94. package/dist/executer/kubernetes-service.js +116 -48
  95. package/dist/executer/label-values.js +29 -46
  96. package/dist/executer/label-values.spec.js +61 -0
  97. package/dist/executer/lazy-resolver.js +16 -0
  98. package/dist/executer/lazy-resolver.spec.js +20 -0
  99. package/dist/executer/local-task.js +44 -0
  100. package/dist/executer/process-manager.js +16 -70
  101. package/dist/executer/process-manager.spec.js +39 -76
  102. package/dist/executer/reset-work-tree.js +30 -0
  103. package/dist/executer/scheduler/check-for-loop.js +17 -7
  104. package/dist/executer/scheduler/{scheduler-state.js → dependency-state.js} +1 -1
  105. package/dist/executer/scheduler/enqueue-next.js +83 -19
  106. package/dist/executer/scheduler/enqueue-next.spec.js +136 -0
  107. package/dist/executer/scheduler/{node-state.js → need-state.js} +1 -1
  108. package/dist/{parser/build-file.js → executer/scheduler/task-state.js} +1 -1
  109. package/dist/executer/set-user-permission.js +1 -1
  110. package/dist/executer/state-resolver.js +61 -0
  111. package/dist/executer/state-resolver.spec.js +37 -0
  112. package/dist/executer/state.js +37 -31
  113. package/dist/executer/state.spec.js +66 -0
  114. package/dist/executer/states.spec.js +14 -0
  115. package/dist/executer/watch-loop.js +68 -0
  116. package/dist/executer/watch-state-key.js +44 -0
  117. package/dist/executer/work-scope.js +1 -5
  118. package/dist/file/get-file-context.js +24 -3
  119. package/dist/file/get-file-context.spec.js +178 -0
  120. package/dist/file/move-files.js +2 -2
  121. package/dist/file/move-files.spec.js +48 -0
  122. package/dist/index.js +7 -8
  123. package/dist/json-schema.js +12 -0
  124. package/dist/kubernetes/apply.js +34 -0
  125. package/dist/kubernetes/await-running-state.js +71 -0
  126. package/dist/kubernetes/ensure-http-route.js +53 -0
  127. package/dist/kubernetes/ensure-http-route.spec.js +70 -0
  128. package/dist/kubernetes/ensure-ingress.js +54 -0
  129. package/dist/kubernetes/ensure-kubernetes-deployment-exists.js +105 -0
  130. package/dist/kubernetes/ensure-kubernetes-persistent-volume-claim-exists.js +40 -0
  131. package/dist/kubernetes/ensure-kubernetes-service-exists.js +36 -0
  132. package/dist/kubernetes/ensure-namespace.js +43 -0
  133. package/dist/kubernetes/ensure-namespace.spec.js +39 -0
  134. package/dist/kubernetes/ensure-persistent-data.js +158 -0
  135. package/dist/kubernetes/get-service-ip.js +11 -0
  136. package/dist/kubernetes/kubernetes-instance.js +48 -0
  137. package/dist/kubernetes/remove-persistent-data.js +19 -0
  138. package/dist/kubernetes/resolve-pod-name.js +42 -0
  139. package/dist/kubernetes/resolve-pod-name.spec.js +81 -0
  140. package/dist/kubernetes/resources.js +12 -0
  141. package/dist/kubernetes/restore-kubernetes-data.js +42 -0
  142. package/dist/kubernetes/store-kubernetes-data.js +39 -0
  143. package/dist/kubernetes/volumes.js +64 -0
  144. package/dist/log.js +69 -69
  145. package/dist/log.spec.js +131 -0
  146. package/dist/logging/grouped-logger.js +17 -15
  147. package/dist/logging/grouped-logger.spec.js +84 -0
  148. package/dist/logging/interactive-logger.js +1 -1
  149. package/dist/logging/interactive-logger.spec.js +57 -0
  150. package/dist/logging/live-logger.js +2 -2
  151. package/dist/logging/live-logger.spec.js +37 -0
  152. package/dist/logging/loggers.spec.js +154 -0
  153. package/dist/optimizer/calculate-checksum.spec.js +34 -0
  154. package/dist/optimizer/get-cache-directory.js +6 -6
  155. package/dist/optimizer/get-cache-directory.spec.js +59 -0
  156. package/dist/optimizer/get-work-cache-stats.js +53 -0
  157. package/dist/optimizer/get-work-cache-stats.spec.js +79 -0
  158. package/dist/{parser/build-file-task.js → optimizer/work-cache-stats.js} +1 -1
  159. package/dist/optimizer/work-task-cache-description.js +25 -0
  160. package/dist/optimizer/work-task-cache-description.spec.js +45 -0
  161. package/dist/parser/default-build-file.js +14 -7
  162. package/dist/parser/default-build-file.spec.js +48 -0
  163. package/dist/parser/parse-label-arguments.spec.js +27 -0
  164. package/dist/parser/read-build-file.js +2 -13
  165. package/dist/parser/read-build-file.spec.js +89 -0
  166. package/dist/parser/read-env-file.js +4 -5
  167. package/dist/parser/read-env-file.spec.js +42 -0
  168. package/dist/planner/utils/append-work-dependencies.js +55 -0
  169. package/dist/planner/utils/append-work-environment.js +22 -0
  170. package/dist/planner/utils/append-work-needs.js +18 -0
  171. package/dist/planner/utils/append-work-service.js +107 -0
  172. package/dist/planner/utils/append-work-service.spec.js +71 -0
  173. package/dist/planner/utils/append-work-task.js +81 -0
  174. package/dist/planner/utils/get-container-user.js +14 -0
  175. package/dist/planner/utils/get-container-user.spec.js +30 -0
  176. package/dist/planner/utils/get-default-kube-config.js +10 -0
  177. package/dist/planner/utils/get-default-kube-config.spec.js +11 -0
  178. package/dist/planner/utils/get-work-runtime.js +44 -0
  179. package/dist/planner/utils/normalize-path.js +1 -1
  180. package/dist/planner/utils/normalize-path.spec.js +24 -0
  181. package/dist/planner/utils/parse-work-command.js +80 -0
  182. package/dist/planner/utils/parse-work-command.spec.js +21 -0
  183. package/dist/planner/utils/parse-work-generate.js +38 -0
  184. package/dist/planner/utils/parse-work-generate.spec.js +45 -0
  185. package/dist/planner/utils/{parse-work-node-mount.js → parse-work-mount.js} +10 -7
  186. package/dist/planner/utils/{parse-work-node-mount.spec.js → parse-work-mount.spec.js} +14 -11
  187. package/dist/planner/utils/parse-work-mounts.js +13 -0
  188. package/dist/planner/utils/parse-work-mounts.spec.js +19 -0
  189. package/dist/planner/utils/{parse-work-node-port.js → parse-work-port.js} +11 -8
  190. package/dist/planner/utils/parse-work-port.spec.js +24 -0
  191. package/dist/planner/utils/parse-work-ports.js +10 -0
  192. package/dist/planner/utils/parse-work-ports.spec.js +24 -0
  193. package/dist/planner/utils/parse-work-source.js +72 -0
  194. package/dist/planner/utils/parse-work-source.spec.js +58 -0
  195. package/dist/planner/utils/parse-work-volume.js +45 -0
  196. package/dist/planner/utils/parse-work-volume.spec.js +18 -0
  197. package/dist/planner/utils/plan-work-tasks.js +41 -0
  198. package/dist/planner/utils/plan-work-tasks.spec.js +30 -0
  199. package/dist/planner/utils/plan-work-volume.js +1 -0
  200. package/dist/planner/utils/plan-work-volume.spec.js +33 -0
  201. package/dist/planner/utils/split-name.js +2 -2
  202. package/dist/planner/utils/split-name.spec.js +16 -0
  203. package/dist/planner/utils/template-value.js +1 -2
  204. package/dist/planner/utils/template-value.spec.js +14 -0
  205. package/dist/planner/validate.js +71 -38
  206. package/dist/planner/validate.spec.js +251 -0
  207. package/dist/planner/work-cache-id.js +12 -0
  208. package/dist/planner/work-cache-id.spec.js +173 -0
  209. package/dist/planner/work-command.js +3 -0
  210. package/dist/planner/work-environment.js +3 -0
  211. package/dist/planner/work-healthcheck.js +3 -0
  212. package/dist/planner/{work-node-status.js → work-item-status.js} +16 -62
  213. package/dist/{parser/build-file-service.js → planner/work-item-validation.js} +1 -1
  214. package/dist/planner/work-item.js +16 -0
  215. package/dist/{optimizer/work-node-cache-stats.js → planner/work-kubernetes-selector.js} +1 -1
  216. package/dist/planner/{work-nodes.js → work-port.js} +1 -1
  217. package/dist/planner/work-runtime-docker.js +224 -0
  218. package/dist/planner/work-runtime-kubernetes.js +264 -0
  219. package/dist/planner/work-runtime-local.js +109 -0
  220. package/dist/planner/work-runtime-local.spec.js +193 -0
  221. package/dist/planner/work-service-id.js +15 -5
  222. package/dist/planner/work-source.js +3 -0
  223. package/dist/planner/work-task.js +8 -0
  224. package/dist/program-commands.spec.js +84 -0
  225. package/dist/program.js +219 -73
  226. package/dist/program.spec.js +34 -11
  227. package/dist/run-program.js +28 -0
  228. package/dist/{executer/process.js → runtime/runtime.js} +1 -1
  229. package/dist/schema/build-file-base-task-schema.js +27 -0
  230. package/dist/schema/build-file-container-service-schema.js +28 -0
  231. package/dist/schema/build-file-container-task-schema.js +13 -0
  232. package/dist/schema/build-file-environment-schema-ingress.js +14 -0
  233. package/dist/schema/build-file-environment-schema.js +23 -0
  234. package/dist/schema/build-file-kubernetes-service-schema.js +17 -0
  235. package/dist/schema/build-file-kubernetes-service-selector-schema.js +9 -0
  236. package/dist/schema/build-file-local-platform-schema.js +9 -0
  237. package/dist/schema/build-file-local-task-schema.js +12 -0
  238. package/dist/schema/build-file-need-schema.js +12 -0
  239. package/dist/schema/build-file-schema.js +23 -0
  240. package/dist/schema/build-file-schema.spec.js +61 -0
  241. package/dist/schema/build-file-service-container-healthcheck.js +8 -0
  242. package/dist/schema/build-file-service-schema.js +15 -0
  243. package/dist/schema/build-file-task-command-schema.js +12 -0
  244. package/dist/schema/build-file-task-schema.js +12 -0
  245. package/dist/schema/build-file-volume-schema.js +14 -0
  246. package/dist/schema/cache-schema.js +31 -0
  247. package/dist/schema/doc-build-files.spec.js +223 -0
  248. package/dist/schema/envs-schema.js +6 -0
  249. package/dist/schema/labels-schema.js +6 -0
  250. package/dist/schema/parse-context.js +3 -0
  251. package/dist/schema/parse-error.js +12 -0
  252. package/dist/schema/parse-error.spec.js +18 -0
  253. package/dist/schema/reference-parser.js +209 -0
  254. package/dist/schema/reference-parser.spec.js +83 -0
  255. package/dist/schema/schema-parser.js +66 -0
  256. package/dist/schema/schema-parser.spec.js +80 -0
  257. package/dist/schema/type-guards.spec.js +23 -0
  258. package/dist/schema/work-scope-parser.js +77 -0
  259. package/dist/schema/work-scope-parser.spec.js +66 -0
  260. package/dist/service/update-service-status.js +11 -0
  261. package/dist/service/update-service-status.spec.js +27 -0
  262. package/dist/testing/ensure-local-registry.js +134 -0
  263. package/dist/testing/example-test-suite.js +16 -18
  264. package/dist/testing/expect.js +46 -22
  265. package/dist/testing/http-get.js +21 -0
  266. package/dist/testing/integration/cache.spec.js +13 -14
  267. package/dist/testing/integration/cancellation.spec.js +14 -9
  268. package/dist/testing/integration/clean.spec.js +14 -11
  269. package/dist/testing/integration/cmd.spec.js +1 -1
  270. package/dist/testing/integration/concurrency.spec.js +3 -3
  271. package/dist/testing/integration/docker-package-registry.spec.js +44 -0
  272. package/dist/testing/integration/docker-service-crash.spec.js +36 -0
  273. package/dist/testing/integration/docker.spec.js +4 -3
  274. package/dist/testing/integration/env.spec.js +9 -8
  275. package/dist/testing/integration/environment.spec.js +97 -0
  276. package/dist/testing/integration/error.spec.js +5 -4
  277. package/dist/testing/integration/export.spec.js +22 -0
  278. package/dist/testing/integration/extend.spec.js +9 -12
  279. package/dist/testing/integration/glob.spec.js +12 -20
  280. package/dist/testing/integration/include.spec.js +3 -3
  281. package/dist/testing/integration/invalid.spec.js +2 -3
  282. package/dist/testing/integration/invalid_loop.spec.js +49 -6
  283. package/dist/testing/integration/k8s-state-cache.spec.js +41 -0
  284. package/dist/testing/integration/kubernetes-service.spec.js +148 -0
  285. package/dist/testing/integration/kubernetes.spec.js +93 -9
  286. package/dist/testing/integration/labels.spec.js +6 -11
  287. package/dist/testing/integration/local.spec.js +1 -1
  288. package/dist/testing/integration/monorepo.spec.js +4 -4
  289. package/dist/testing/integration/multi-line.spec.js +3 -3
  290. package/dist/testing/integration/reference.spec.js +4 -5
  291. package/dist/testing/integration/services.spec.js +22 -4
  292. package/dist/testing/integration/store.spec.js +15 -16
  293. package/dist/testing/integration/unknown.spec.js +20 -18
  294. package/dist/testing/integration/validate.spec.js +143 -26
  295. package/dist/testing/integration/watch-dependency.spec.js +11 -8
  296. package/dist/testing/integration/watch.spec.js +15 -16
  297. package/dist/testing/requires-kubernetes.js +18 -0
  298. package/dist/testing/requires-linux-containers.js +18 -0
  299. package/dist/testing/requires-windows-containers.js +18 -0
  300. package/dist/testing/test-case.js +75 -0
  301. package/dist/testing/test-streams.js +28 -0
  302. package/dist/testing/testing-timeout.js +32 -0
  303. package/dist/utils/abort-event.js +10 -4
  304. package/dist/utils/abort-event.spec.js +46 -0
  305. package/dist/utils/buffer-context.js +44 -0
  306. package/dist/utils/buffer-context.spec.js +38 -0
  307. package/dist/utils/ci.spec.js +53 -0
  308. package/dist/utils/emitter.spec.js +34 -0
  309. package/dist/utils/empty-writable.spec.js +18 -0
  310. package/dist/utils/environment-config.js +4 -1
  311. package/dist/utils/environment-config.spec.js +26 -0
  312. package/dist/utils/fail-never.spec.js +9 -0
  313. package/dist/version.js +9 -0
  314. package/dist/version.spec.js +12 -0
  315. package/package.json +41 -23
  316. package/specs/build-file/caches/spec.md +114 -0
  317. package/specs/build-file/environment-variables/spec.md +82 -0
  318. package/specs/build-file/includes/spec.md +60 -0
  319. package/specs/build-file/references/spec.md +56 -0
  320. package/specs/build-file/spec.md +62 -0
  321. package/specs/cli/clean/spec.md +85 -0
  322. package/specs/cli/down/spec.md +85 -0
  323. package/specs/cli/execute/spec.md +101 -0
  324. package/specs/cli/init/spec.md +64 -0
  325. package/specs/cli/ls/spec.md +66 -0
  326. package/specs/cli/package/spec.md +110 -0
  327. package/specs/cli/spec.md +73 -0
  328. package/specs/cli/store-restore/spec.md +74 -0
  329. package/specs/cli/up/spec.md +80 -0
  330. package/specs/cli/validate/spec.md +70 -0
  331. package/specs/labels/spec.md +91 -0
  332. package/specs/service/container/spec.md +120 -0
  333. package/specs/service/kubernetes/spec.md +97 -0
  334. package/specs/service/spec.md +105 -0
  335. package/specs/task/caching/spec.md +107 -0
  336. package/specs/task/container/spec.md +118 -0
  337. package/specs/task/dependencies/spec.md +70 -0
  338. package/specs/task/extending/spec.md +74 -0
  339. package/specs/task/kubernetes/spec.md +125 -0
  340. package/specs/task/needs/spec.md +59 -0
  341. package/specs/task/spec.md +87 -0
  342. package/specs/task/watching/spec.md +69 -0
  343. package/dist/console/console-context-mock.js +0 -14
  344. package/dist/environment/get-process-env.js +0 -15
  345. package/dist/executer/create-scheduler-state.js +0 -32
  346. package/dist/executer/docker-node.js +0 -123
  347. package/dist/executer/hierarchy-scheduler.js +0 -94
  348. package/dist/executer/local-node.js +0 -57
  349. package/dist/executer/schedule.js +0 -137
  350. package/dist/executer/start-node.js +0 -67
  351. package/dist/executer/watch-node.js +0 -56
  352. package/dist/executer/watch-service.js +0 -54
  353. package/dist/file/get-file-context-mock.js +0 -187
  354. package/dist/file/get-file-context-mock.spec.js +0 -56
  355. package/dist/get-work-context.js +0 -29
  356. package/dist/optimizer/get-work-node-cache-stats.js +0 -104
  357. package/dist/optimizer/read-work-node-cache.js +0 -19
  358. package/dist/optimizer/work-node-cache-description.js +0 -32
  359. package/dist/optimizer/write-work-node-cache.js +0 -21
  360. package/dist/parser/build-file-task-command.js +0 -3
  361. package/dist/parser/build-file-task-platform.js +0 -3
  362. package/dist/parser/build-file-task-source.js +0 -3
  363. package/dist/parser/get-build-file.js +0 -9
  364. package/dist/parser/parse-boolean.js +0 -29
  365. package/dist/parser/parse-boolean.spec.js +0 -48
  366. package/dist/parser/parse-build-file-references.js +0 -35
  367. package/dist/parser/parse-build-file-services.js +0 -58
  368. package/dist/parser/parse-build-file-task-command.js +0 -36
  369. package/dist/parser/parse-build-file-task-source.js +0 -63
  370. package/dist/parser/parse-build-file.js +0 -125
  371. package/dist/parser/parse-context.js +0 -13
  372. package/dist/parser/parse-envs.js +0 -29
  373. package/dist/parser/parse-healthcheck.js +0 -28
  374. package/dist/parser/parse-service-selector.js +0 -39
  375. package/dist/parser/parse-string-array.js +0 -20
  376. package/dist/parser/parse-string-map.js +0 -30
  377. package/dist/parser/parse-string.js +0 -20
  378. package/dist/planner/utils/get-container-mounts.js +0 -24
  379. package/dist/planner/utils/parse-work-service-volume.js +0 -23
  380. package/dist/planner/utils/plan-work-command.js +0 -21
  381. package/dist/planner/utils/plan-work-dependency.js +0 -36
  382. package/dist/planner/utils/plan-work-node.js +0 -293
  383. package/dist/planner/utils/plan-work-nodes.js +0 -78
  384. package/dist/planner/utils/plan-work-tree.js +0 -15
  385. package/dist/planner/work-context.js +0 -23
  386. package/dist/planner/work-node-command.js +0 -3
  387. package/dist/planner/work-node-id.js +0 -12
  388. package/dist/planner/work-node-id.spec.js +0 -106
  389. package/dist/planner/work-node-path.js +0 -2
  390. package/dist/planner/work-node-source.js +0 -3
  391. package/dist/planner/work-node-validation.js +0 -3
  392. package/dist/planner/work-node.js +0 -8
  393. package/dist/planner/work-service-volume.js +0 -3
  394. package/dist/planner/work-services.js +0 -3
  395. package/dist/start-watch-processes.js +0 -28
  396. package/dist/testing/cli.js +0 -73
  397. package/dist/testing/create-build-file.js +0 -9
  398. package/dist/testing/get-logger.js +0 -23
  399. package/dist/testing/get-node.js +0 -12
  400. package/dist/testing/get-test-context.js +0 -19
  401. package/dist/testing/integration/program.spec.js +0 -25
  402. package/dist/testing/lazy.js +0 -17
  403. package/dist/testing/start-watch-processes.js +0 -29
  404. package/dist/testing/test-suite-options.js +0 -3
  405. package/dist/utils/abortable-function.js +0 -71
  406. package/logs/cache-console.log +0 -0
  407. package/logs/cache-status.log +0 -6
  408. package/logs/cache-stout.log +0 -0
  409. package/logs/cancellation-console.log +0 -0
  410. package/logs/cancellation-status.log +0 -3
  411. package/logs/cancellation-stout.log +0 -3
  412. package/logs/clean-console.log +0 -0
  413. package/logs/clean-status.log +0 -37
  414. package/logs/clean-stout.log +0 -95
  415. package/logs/cmd-console.log +0 -0
  416. package/logs/cmd-status.log +0 -8
  417. package/logs/cmd-stout.log +0 -9
  418. package/logs/concurrency-console.log +0 -0
  419. package/logs/concurrency-status.log +0 -14
  420. package/logs/concurrency-stout.log +0 -88
  421. package/logs/docker-console.log +0 -0
  422. package/logs/docker-status.log +0 -14
  423. package/logs/docker-stout.log +0 -39
  424. package/logs/env-console.log +0 -1
  425. package/logs/env-status.log +0 -1
  426. package/logs/env-stout.log +0 -0
  427. package/logs/error-console.log +0 -0
  428. package/logs/error-status.log +0 -10
  429. package/logs/error-stout.log +0 -36
  430. package/logs/extend-console.log +0 -0
  431. package/logs/extend-status.log +0 -1
  432. package/logs/extend-stout.log +0 -0
  433. package/logs/glob-console.log +0 -28
  434. package/logs/glob-status.log +0 -23
  435. package/logs/glob-stout.log +0 -52
  436. package/logs/hello-world-node-console.log +0 -0
  437. package/logs/hello-world-node-status.log +0 -37
  438. package/logs/hello-world-node-stout.log +0 -41
  439. package/logs/include-console.log +0 -0
  440. package/logs/include-status.log +0 -3
  441. package/logs/include-stout.log +0 -0
  442. package/logs/invalid-console.log +0 -0
  443. package/logs/invalid-status.log +0 -1
  444. package/logs/invalid-stout.log +0 -0
  445. package/logs/invalid_loop-console.log +0 -0
  446. package/logs/invalid_loop-status.log +0 -1
  447. package/logs/invalid_loop-stout.log +0 -11
  448. package/logs/labels-console.log +0 -0
  449. package/logs/labels-status.log +0 -1
  450. package/logs/labels-stout.log +0 -0
  451. package/logs/local-console.log +0 -0
  452. package/logs/local-status.log +0 -7
  453. package/logs/local-stout.log +0 -8
  454. package/logs/monorepo-console.log +0 -0
  455. package/logs/monorepo-status.log +0 -152
  456. package/logs/monorepo-stout.log +0 -2354
  457. package/logs/multi-line-console.log +0 -0
  458. package/logs/multi-line-status.log +0 -1
  459. package/logs/multi-line-stout.log +0 -0
  460. package/logs/reference-console.log +0 -0
  461. package/logs/reference-status.log +0 -5
  462. package/logs/reference-stout.log +0 -0
  463. package/logs/services-console.log +0 -0
  464. package/logs/services-status.log +0 -129
  465. package/logs/services-stout.log +0 -639
  466. package/logs/store-restore-console.log +0 -0
  467. package/logs/store-restore-status.log +0 -40
  468. package/logs/store-restore-stout.log +0 -97
  469. package/logs/unknown-console.log +0 -3
  470. package/logs/unknown-status.log +0 -1
  471. package/logs/unknown-stout.log +0 -0
  472. package/logs/validate-console.log +0 -0
  473. package/logs/validate-status.log +0 -2
  474. package/logs/validate-stout.log +0 -0
  475. package/logs/watch-console.log +0 -0
  476. package/logs/watch-dependency-console.log +0 -0
  477. package/logs/watch-dependency-status.log +0 -176
  478. package/logs/watch-dependency-stout.log +0 -779
  479. package/logs/watch-status.log +0 -100
  480. package/logs/watch-stout.log +0 -349
@@ -2,30 +2,29 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const get_test_suite_1 = require("../get-test-suite");
4
4
  const path_1 = require("path");
5
+ const requires_linux_containers_1 = require("../requires-linux-containers");
5
6
  describe('watch', () => {
6
7
  const suite = (0, get_test_suite_1.getTestSuite)('watch', ['.hammerkit.yaml', 'src', 'package.json', 'package-lock.json', 'tsconfig.json']);
7
8
  afterAll(() => suite.close());
8
- it('should run watch task and cancel', async () => {
9
- const { cli, environment } = await suite.setup({ taskName: 'api' });
10
- const apiNode = cli.node('api');
11
- const exec = cli.execWatch({ watch: true });
12
- exec.processManager.on((evt) => {
13
- if (evt.context.id === apiNode.id && evt.type === 'started') {
9
+ it('should run watch task and cancel', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
10
+ const { cli, environment } = await suite.setup({ filterLabels: { task: ['dev'] } });
11
+ const exec = await cli.up({ watch: true });
12
+ exec.state.on('test-status', (evt) => {
13
+ if (evt.services['api'].state.current.type === 'running') {
14
14
  environment.abortCtrl.abort();
15
15
  }
16
16
  });
17
17
  const result = await exec.start();
18
18
  expect(result.success).toBeFalsy();
19
- expect(result.state.node[apiNode.id].type).toEqual('canceled');
20
- });
21
- it('should restart task if dependency updates', async () => {
22
- const { cli, environment } = await suite.setup({ taskName: 'api' });
23
- const apiNode = cli.node('api');
24
- const exec = cli.execWatch({ watch: true });
19
+ expect(result.state.services['api'].state.current.type).toEqual('canceled');
20
+ }), 900000);
21
+ it('should restart task if dependency updates', (0, requires_linux_containers_1.requiresLinuxContainers)(async () => {
22
+ const { cli, environment } = await suite.setup({ filterLabels: { task: ['dev'] } });
23
+ const exec = await cli.up({ watch: true });
25
24
  let appendedFile = false;
26
25
  let restarted = false;
27
- exec.processManager.on((evt) => {
28
- if (evt.type === 'started' && evt.context.id === apiNode.id) {
26
+ exec.state.on('test-status', (evt) => {
27
+ if (evt.services['api'].state.current.type === 'running') {
29
28
  if (!appendedFile) {
30
29
  appendedFile = true;
31
30
  environment.file.appendFile((0, path_1.join)(environment.cwd, 'package.json'), '\n');
@@ -40,7 +39,7 @@ describe('watch', () => {
40
39
  expect(appendedFile).toBeTruthy();
41
40
  expect(restarted).toBeTruthy();
42
41
  expect(result.success).toBeFalsy();
43
- expect(result.state.node[apiNode.id].type).toEqual('canceled');
44
- });
42
+ expect(result.state.services['api'].state.current.type).toEqual('canceled');
43
+ }), 900000);
45
44
  });
46
45
  //# sourceMappingURL=watch.spec.js.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requiresKubernetes = void 0;
4
+ const ci_1 = require("../utils/ci");
5
+ function requiresKubernetes(fn) {
6
+ if (process.env.CLUSTER_NAME) {
7
+ return fn;
8
+ }
9
+ if (process.env.HAMMERKIT_FULL_INTEGRATION) {
10
+ return () => Promise.reject(new Error('CLUSTER_NAME not set but HAMMERKIT_FULL_INTEGRATION is on'));
11
+ }
12
+ if (ci_1.isCI) {
13
+ return () => Promise.resolve();
14
+ }
15
+ return fn;
16
+ }
17
+ exports.requiresKubernetes = requiresKubernetes;
18
+ //# sourceMappingURL=requires-kubernetes.js.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requiresLinuxContainers = void 0;
4
+ const ci_1 = require("../utils/ci");
5
+ function requiresLinuxContainers(fn) {
6
+ if (process.env.LINUX_CONTAINERS) {
7
+ return fn;
8
+ }
9
+ if (process.env.HAMMERKIT_FULL_INTEGRATION) {
10
+ return () => Promise.reject(new Error('LINUX_CONTAINERS not set but HAMMERKIT_FULL_INTEGRATION is on'));
11
+ }
12
+ if (ci_1.isCI) {
13
+ return () => Promise.resolve();
14
+ }
15
+ return fn;
16
+ }
17
+ exports.requiresLinuxContainers = requiresLinuxContainers;
18
+ //# sourceMappingURL=requires-linux-containers.js.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requiresWindowsContainers = void 0;
4
+ const ci_1 = require("../utils/ci");
5
+ function requiresWindowsContainers(fn) {
6
+ if (process.env.WINDOWS_CONTAINERS) {
7
+ return fn;
8
+ }
9
+ if (process.env.HAMMERKIT_FULL_INTEGRATION) {
10
+ return () => Promise.reject(new Error('WINDOWS_CONTAINERS not set but HAMMERKIT_FULL_INTEGRATION is on'));
11
+ }
12
+ if (ci_1.isCI) {
13
+ return () => Promise.resolve();
14
+ }
15
+ return fn;
16
+ }
17
+ exports.requiresWindowsContainers = requiresWindowsContainers;
18
+ //# sourceMappingURL=requires-windows-containers.js.map
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTestCase = exports.getTestRunId = void 0;
4
+ const path_1 = require("path");
5
+ const get_file_context_1 = require("../file/get-file-context");
6
+ const log_1 = require("../log");
7
+ const work_item_status_1 = require("../planner/work-item-status");
8
+ const program_1 = require("../program");
9
+ const yaml_1 = require("yaml");
10
+ const run_program_1 = require("../run-program");
11
+ const test_streams_1 = require("./test-streams");
12
+ function getTestRunId(name) {
13
+ const base = process.env.HAMMERKIT_TEST_RUN_ID ?? `local-${process.pid}`;
14
+ return `${base}-${name}`
15
+ .toLowerCase()
16
+ .replace(/[^a-z0-9-]+/g, '-')
17
+ .replace(/^-+|-+$/g, '')
18
+ .slice(0, 63);
19
+ }
20
+ exports.getTestRunId = getTestRunId;
21
+ function createTestCase(name, files) {
22
+ const runId = getTestRunId(name);
23
+ return {
24
+ runId,
25
+ async shell(args) {
26
+ await this.setup(async (cwd, env) => {
27
+ await (0, run_program_1.runProgram)(env, args, true);
28
+ });
29
+ },
30
+ async setup(fn) {
31
+ const path = (0, path_1.join)(process.cwd(), 'temp', name);
32
+ const file = (0, get_file_context_1.getFileContext)(path);
33
+ const statusStream = (0, test_streams_1.memoryStream)();
34
+ try {
35
+ await file.remove(path);
36
+ await file.createDirectory(path);
37
+ const environment = {
38
+ processEnvs: { ...process.env, HAMMERKIT_TEST_RUN_ID: runId },
39
+ abortCtrl: new AbortController(),
40
+ cwd: path,
41
+ file,
42
+ console: (0, log_1.consoleContext)((0, test_streams_1.emptyStream)()),
43
+ status: (0, work_item_status_1.statusConsole)(statusStream.stream),
44
+ stdout: (0, test_streams_1.emptyStream)(),
45
+ stderr: (0, test_streams_1.emptyStream)(),
46
+ stdoutColumns: 80,
47
+ };
48
+ for (const [fileName, fileContent] of Object.entries(files)) {
49
+ await file.createDirectory((0, path_1.dirname)((0, path_1.join)(path, fileName)));
50
+ await file.writeFile((0, path_1.join)(path, fileName), typeof fileContent === 'string' ? fileContent : (0, yaml_1.stringify)(fileContent));
51
+ }
52
+ await fn(path, environment);
53
+ }
54
+ catch (e) {
55
+ process.stdout.write(statusStream.read());
56
+ throw e;
57
+ }
58
+ },
59
+ async cli(scope, fn) {
60
+ return this.setup(async (cwd, environment) => {
61
+ const fileName = (0, path_1.join)(cwd, '.hammerkit.yaml');
62
+ environment.processEnvs = { ...environment.processEnvs, ...(scope.envs ?? {}) };
63
+ const cli = await (0, program_1.createCli)(fileName, environment, scope);
64
+ // also clear the persistent backend cache (~/.hammerkit/remote-cache)
65
+ // so results don't leak between test runs on the same machine.
66
+ await cli.clean({ cache: true });
67
+ if (fn) {
68
+ await fn(cli, environment);
69
+ }
70
+ });
71
+ },
72
+ };
73
+ }
74
+ exports.createTestCase = createTestCase;
75
+ //# sourceMappingURL=test-case.js.map
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.memoryStream = exports.emptyStream = void 0;
4
+ const stream_1 = require("stream");
5
+ function emptyStream() {
6
+ const stream = new stream_1.Writable();
7
+ stream._write = function (_chunk, _encoding, done) {
8
+ done();
9
+ };
10
+ return stream;
11
+ }
12
+ exports.emptyStream = emptyStream;
13
+ function memoryStream() {
14
+ const stream = new stream_1.Writable();
15
+ const chunks = [];
16
+ stream._write = function (chunk, encoding, done) {
17
+ chunks.push(chunk.toString());
18
+ done();
19
+ };
20
+ return {
21
+ stream,
22
+ read() {
23
+ return chunks.join('');
24
+ },
25
+ };
26
+ }
27
+ exports.memoryStream = memoryStream;
28
+ //# sourceMappingURL=test-streams.js.map
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.testingTimeout = void 0;
4
+ const plan_work_tasks_1 = require("../planner/utils/plan-work-tasks");
5
+ async function testingTimeout(exec, timeout) {
6
+ const timer = setTimeout(() => {
7
+ for (const task of (0, plan_work_tasks_1.iterateWorkTasks)(exec.state.current)) {
8
+ printWorkItem(task);
9
+ }
10
+ for (const service of (0, plan_work_tasks_1.iterateWorkServices)(exec.state.current)) {
11
+ printWorkItem(service);
12
+ }
13
+ }, (timeout || 45 * 1000) - 2000);
14
+ try {
15
+ return await exec.start();
16
+ }
17
+ finally {
18
+ clearTimeout(timer);
19
+ }
20
+ }
21
+ exports.testingTimeout = testingTimeout;
22
+ function printWorkItem(task) {
23
+ const messages = [` - ${task.name}: ${task.state.current.type}`];
24
+ for (const log of task.status.logs()) {
25
+ messages.push(` console ${log.console}: ${log.message}`);
26
+ }
27
+ for (const log of task.status.read()) {
28
+ messages.push(` status ${log.level}: ${log.message}`);
29
+ }
30
+ process.stdout.write(messages.join('\n'));
31
+ }
32
+ //# sourceMappingURL=testing-timeout.js.map
@@ -4,12 +4,18 @@ exports.waitOnAbort = exports.listenOnAbort = void 0;
4
4
  function listenOnAbort(abort, callback) {
5
5
  if (abort.aborted) {
6
6
  callback();
7
- return;
7
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
8
+ return { close() { } };
8
9
  }
9
- const listener = abort;
10
- listener.addEventListener('abort', () => {
10
+ const eventListener = () => {
11
11
  callback();
12
- }, { once: true });
12
+ };
13
+ abort.addEventListener('abort', eventListener, { once: true });
14
+ return {
15
+ close: () => {
16
+ abort.removeEventListener('abort', eventListener);
17
+ },
18
+ };
13
19
  }
14
20
  exports.listenOnAbort = listenOnAbort;
15
21
  function waitOnAbort(abort) {
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const abort_event_1 = require("./abort-event");
4
+ describe('abort-event', () => {
5
+ describe('listenOnAbort', () => {
6
+ it('fires immediately when the signal is already aborted', () => {
7
+ const ctrl = new AbortController();
8
+ ctrl.abort();
9
+ const cb = vi.fn();
10
+ const handle = (0, abort_event_1.listenOnAbort)(ctrl.signal, cb);
11
+ expect(cb).toHaveBeenCalledTimes(1);
12
+ // close on a pre-aborted listener is a no-op; calling it must not throw.
13
+ expect(() => handle.close()).not.toThrow();
14
+ });
15
+ it('fires when the signal is aborted later', () => {
16
+ const ctrl = new AbortController();
17
+ const cb = vi.fn();
18
+ (0, abort_event_1.listenOnAbort)(ctrl.signal, cb);
19
+ expect(cb).not.toHaveBeenCalled();
20
+ ctrl.abort();
21
+ expect(cb).toHaveBeenCalledTimes(1);
22
+ });
23
+ it('does not fire after close()', () => {
24
+ const ctrl = new AbortController();
25
+ const cb = vi.fn();
26
+ const handle = (0, abort_event_1.listenOnAbort)(ctrl.signal, cb);
27
+ handle.close();
28
+ ctrl.abort();
29
+ expect(cb).not.toHaveBeenCalled();
30
+ });
31
+ });
32
+ describe('waitOnAbort', () => {
33
+ it('resolves immediately when already aborted', async () => {
34
+ const ctrl = new AbortController();
35
+ ctrl.abort();
36
+ await expect((0, abort_event_1.waitOnAbort)(ctrl.signal)).resolves.toBeUndefined();
37
+ });
38
+ it('resolves when the signal is aborted later', async () => {
39
+ const ctrl = new AbortController();
40
+ const pending = (0, abort_event_1.waitOnAbort)(ctrl.signal);
41
+ ctrl.abort();
42
+ await expect(pending).resolves.toBeUndefined();
43
+ });
44
+ });
45
+ });
46
+ //# sourceMappingURL=abort-event.spec.js.map
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BufferContext = void 0;
4
+ class BufferContext {
5
+ constructor(limit) {
6
+ this.limit = limit;
7
+ this.scopedBuffer = {};
8
+ this.buffer = [];
9
+ }
10
+ add(id, data) {
11
+ this.buffer.push(data);
12
+ if (id in this.scopedBuffer) {
13
+ const scopedBuffer = this.scopedBuffer[id];
14
+ scopedBuffer.push(data);
15
+ if (scopedBuffer.length > this.limit) {
16
+ const removedBuffer = this.buffer.splice(0, 1)[0];
17
+ const bufferIndex = this.buffer.indexOf(removedBuffer);
18
+ if (bufferIndex >= 0) {
19
+ this.buffer.splice(bufferIndex, 1);
20
+ }
21
+ }
22
+ }
23
+ else {
24
+ this.scopedBuffer[id] = [data];
25
+ }
26
+ }
27
+ current(id) {
28
+ if (!(id in this.scopedBuffer)) {
29
+ return null;
30
+ }
31
+ const value = this.scopedBuffer[id];
32
+ return value[value.length - 1];
33
+ }
34
+ get(id) {
35
+ if (id) {
36
+ return this.scopedBuffer[id] ?? [];
37
+ }
38
+ else {
39
+ return this.buffer;
40
+ }
41
+ }
42
+ }
43
+ exports.BufferContext = BufferContext;
44
+ //# sourceMappingURL=buffer-context.js.map
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const buffer_context_1 = require("./buffer-context");
4
+ describe('BufferContext', () => {
5
+ it('returns null for current of an unknown id', () => {
6
+ const ctx = new buffer_context_1.BufferContext(10);
7
+ expect(ctx.current('missing')).toBeNull();
8
+ });
9
+ it('returns an empty array for get of an unknown id', () => {
10
+ const ctx = new buffer_context_1.BufferContext(10);
11
+ expect(ctx.get('missing')).toEqual([]);
12
+ });
13
+ it('tracks the latest value per id', () => {
14
+ const ctx = new buffer_context_1.BufferContext(10);
15
+ ctx.add('a', 1);
16
+ ctx.add('a', 2);
17
+ ctx.add('b', 9);
18
+ expect(ctx.current('a')).toBe(2);
19
+ expect(ctx.current('b')).toBe(9);
20
+ });
21
+ it('keeps per-id and global buffers', () => {
22
+ const ctx = new buffer_context_1.BufferContext(10);
23
+ ctx.add('a', 1);
24
+ ctx.add('b', 2);
25
+ expect(ctx.get('a')).toEqual([1]);
26
+ expect(ctx.get('b')).toEqual([2]);
27
+ expect(ctx.get()).toEqual([1, 2]);
28
+ });
29
+ it('evicts the oldest global entry once an id exceeds the limit', () => {
30
+ const ctx = new buffer_context_1.BufferContext(2);
31
+ ctx.add('a', 1);
32
+ ctx.add('a', 2);
33
+ ctx.add('a', 3);
34
+ expect(ctx.get()).toEqual([2, 3]);
35
+ expect(ctx.current('a')).toBe(3);
36
+ });
37
+ });
38
+ //# sourceMappingURL=buffer-context.spec.js.map
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ // Each `isCI` arm is evaluated once at module load, so the only way to cover
3
+ // every branch of the OR chain is to load the module repeatedly under different
4
+ // process.env. vi.resetModules + a fresh dynamic import gives us that.
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || function (mod) {
22
+ if (mod && mod.__esModule) return mod;
23
+ var result = {};
24
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25
+ __setModuleDefault(result, mod);
26
+ return result;
27
+ };
28
+ const KEYS = ['CI', 'CONTINUOUS_INTEGRATION', 'BUILD_NUMBER', 'RUN_ID'];
29
+ async function loadIsCI(set) {
30
+ for (const k of KEYS)
31
+ delete process.env[k];
32
+ if (set)
33
+ Object.assign(process.env, set);
34
+ vi.resetModules();
35
+ return (await Promise.resolve().then(() => __importStar(require('./ci')))).isCI;
36
+ }
37
+ describe('isCI', () => {
38
+ const original = { ...process.env };
39
+ afterEach(() => {
40
+ for (const k of KEYS)
41
+ delete process.env[k];
42
+ for (const k of KEYS)
43
+ if (k in original)
44
+ process.env[k] = original[k];
45
+ });
46
+ it('is false when no CI env var is set', async () => {
47
+ expect(await loadIsCI()).toBe(false);
48
+ });
49
+ it.each(KEYS)('is true when %s is set', async (key) => {
50
+ expect(await loadIsCI({ [key]: '1' })).toBe(true);
51
+ });
52
+ });
53
+ //# sourceMappingURL=ci.spec.js.map
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const emitter_1 = require("./emitter");
4
+ describe('emitter', () => {
5
+ it('invokes every registered listener on emit', () => {
6
+ const e = (0, emitter_1.emitter)();
7
+ const a = vi.fn();
8
+ const b = vi.fn();
9
+ e.on(a);
10
+ e.on(b);
11
+ e.emit(42);
12
+ expect(a).toHaveBeenCalledWith(42);
13
+ expect(b).toHaveBeenCalledWith(42);
14
+ });
15
+ it('emit with no listeners is a no-op', () => {
16
+ const e = (0, emitter_1.emitter)();
17
+ expect(() => e.emit('noop')).not.toThrow();
18
+ });
19
+ it('close() removes the listener from future emits', () => {
20
+ const e = (0, emitter_1.emitter)();
21
+ const cb = vi.fn();
22
+ const handle = e.on(cb);
23
+ handle.close();
24
+ e.emit(1);
25
+ expect(cb).not.toHaveBeenCalled();
26
+ });
27
+ it('close() called twice is safe (no listener to remove)', () => {
28
+ const e = (0, emitter_1.emitter)();
29
+ const handle = e.on(vi.fn());
30
+ handle.close();
31
+ expect(() => handle.close()).not.toThrow();
32
+ });
33
+ });
34
+ //# sourceMappingURL=emitter.spec.js.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const empty_writable_1 = require("./empty-writable");
4
+ describe('emptyWritable', () => {
5
+ it('accepts writes and invokes the callback', async () => {
6
+ const stream = (0, empty_writable_1.emptyWritable)();
7
+ await new Promise((resolve, reject) => {
8
+ stream.write('hello', (err) => (err ? reject(err) : resolve()));
9
+ });
10
+ });
11
+ it('ends cleanly after writes', async () => {
12
+ const stream = (0, empty_writable_1.emptyWritable)();
13
+ stream.write('a');
14
+ stream.write('b');
15
+ await new Promise((resolve) => stream.end(resolve));
16
+ });
17
+ });
18
+ //# sourceMappingURL=empty-writable.spec.js.map
@@ -3,7 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getEnvironmentConfig = void 0;
4
4
  function getEnvironmentConfig(name, defaultValue) {
5
5
  if (name in process.env) {
6
- return parseInt(`${process.env[name]}`, 0) ?? defaultValue;
6
+ // parseInt returns NaN (not nullish) when the value isn't a number, so use
7
+ // an explicit NaN check; otherwise an invalid env value leaked NaN downstream.
8
+ const parsed = parseInt(`${process.env[name]}`, 10);
9
+ return Number.isNaN(parsed) ? defaultValue : parsed;
7
10
  }
8
11
  else {
9
12
  return defaultValue;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const environment_config_1 = require("./environment-config");
4
+ const VAR = 'HAMMERKIT_TEST_ENV_CONFIG';
5
+ describe('getEnvironmentConfig', () => {
6
+ afterEach(() => {
7
+ delete process.env[VAR];
8
+ });
9
+ it('returns the default when the variable is unset', () => {
10
+ delete process.env[VAR];
11
+ expect((0, environment_config_1.getEnvironmentConfig)(VAR, 7)).toBe(7);
12
+ });
13
+ it('parses an integer env value', () => {
14
+ process.env[VAR] = '42';
15
+ expect((0, environment_config_1.getEnvironmentConfig)(VAR, 7)).toBe(42);
16
+ });
17
+ it('falls back to the default when the env value is not a number', () => {
18
+ process.env[VAR] = 'not-a-number';
19
+ expect((0, environment_config_1.getEnvironmentConfig)(VAR, 7)).toBe(7);
20
+ });
21
+ it('treats an empty string env value as not-a-number and uses the default', () => {
22
+ process.env[VAR] = '';
23
+ expect((0, environment_config_1.getEnvironmentConfig)(VAR, 5)).toBe(5);
24
+ });
25
+ });
26
+ //# sourceMappingURL=environment-config.spec.js.map
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fail_never_1 = require("./fail-never");
4
+ describe('failNever', () => {
5
+ it('throws an error with the given message', () => {
6
+ expect(() => (0, fail_never_1.failNever)('value', 'unexpected')).toThrow('unexpected');
7
+ });
8
+ });
9
+ //# sourceMappingURL=fail-never.spec.js.map
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVersion = void 0;
4
+ function getVersion() {
5
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
6
+ return require('../package.json').version;
7
+ }
8
+ exports.getVersion = getVersion;
9
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const version_1 = require("./version");
4
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
5
+ const pkg = require('../package.json');
6
+ describe('getVersion', () => {
7
+ it('returns the version from package.json', () => {
8
+ expect((0, version_1.getVersion)()).toBe(pkg.version);
9
+ expect((0, version_1.getVersion)()).toMatch(/^\d+\.\d+\.\d+/);
10
+ });
11
+ });
12
+ //# sourceMappingURL=version.spec.js.map