adispatchd 0.0.0-stage → 0.1.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 (396) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -2
  3. package/dist/api/errors.d.ts +27 -0
  4. package/dist/api/errors.js +80 -0
  5. package/dist/api/errors.js.map +1 -0
  6. package/dist/api/index.d.ts +10 -0
  7. package/dist/api/index.js +11 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/api/logs.d.ts +30 -0
  10. package/dist/api/logs.js +88 -0
  11. package/dist/api/logs.js.map +1 -0
  12. package/dist/api/serialize.d.ts +65 -0
  13. package/dist/api/serialize.js +135 -0
  14. package/dist/api/serialize.js.map +1 -0
  15. package/dist/api/server.d.ts +89 -0
  16. package/dist/api/server.js +751 -0
  17. package/dist/api/server.js.map +1 -0
  18. package/dist/api/sse.d.ts +90 -0
  19. package/dist/api/sse.js +225 -0
  20. package/dist/api/sse.js.map +1 -0
  21. package/dist/app.d.ts +173 -0
  22. package/dist/app.js +488 -0
  23. package/dist/app.js.map +1 -0
  24. package/dist/cli/config-validate.d.ts +6 -0
  25. package/dist/cli/config-validate.js +39 -0
  26. package/dist/cli/config-validate.js.map +1 -0
  27. package/dist/cli/control.d.ts +31 -0
  28. package/dist/cli/control.js +186 -0
  29. package/dist/cli/control.js.map +1 -0
  30. package/dist/cli/http-client.d.ts +57 -0
  31. package/dist/cli/http-client.js +174 -0
  32. package/dist/cli/http-client.js.map +1 -0
  33. package/dist/cli/index.d.ts +14 -0
  34. package/dist/cli/index.js +14 -0
  35. package/dist/cli/index.js.map +1 -0
  36. package/dist/cli/init-templates.d.ts +20 -0
  37. package/dist/cli/init-templates.js +275 -0
  38. package/dist/cli/init-templates.js.map +1 -0
  39. package/dist/cli/init.d.ts +16 -0
  40. package/dist/cli/init.js +107 -0
  41. package/dist/cli/init.js.map +1 -0
  42. package/dist/cli/main.d.ts +2 -0
  43. package/dist/cli/main.js +25 -0
  44. package/dist/cli/main.js.map +1 -0
  45. package/dist/cli/program.d.ts +102 -0
  46. package/dist/cli/program.js +133 -0
  47. package/dist/cli/program.js.map +1 -0
  48. package/dist/cli/service.d.ts +27 -0
  49. package/dist/cli/service.js +252 -0
  50. package/dist/cli/service.js.map +1 -0
  51. package/dist/cli/start.d.ts +22 -0
  52. package/dist/cli/start.js +133 -0
  53. package/dist/cli/start.js.map +1 -0
  54. package/dist/cli/workflow-dry-run.d.ts +13 -0
  55. package/dist/cli/workflow-dry-run.js +144 -0
  56. package/dist/cli/workflow-dry-run.js.map +1 -0
  57. package/dist/config/field-catalog.d.ts +33 -0
  58. package/dist/config/field-catalog.js +172 -0
  59. package/dist/config/field-catalog.js.map +1 -0
  60. package/dist/config/filter-schema.d.ts +15 -0
  61. package/dist/config/filter-schema.js +110 -0
  62. package/dist/config/filter-schema.js.map +1 -0
  63. package/dist/config/index.d.ts +15 -0
  64. package/dist/config/index.js +16 -0
  65. package/dist/config/index.js.map +1 -0
  66. package/dist/config/issues.d.ts +27 -0
  67. package/dist/config/issues.js +37 -0
  68. package/dist/config/issues.js.map +1 -0
  69. package/dist/config/loader.d.ts +32 -0
  70. package/dist/config/loader.js +250 -0
  71. package/dist/config/loader.js.map +1 -0
  72. package/dist/config/manager.d.ts +153 -0
  73. package/dist/config/manager.js +276 -0
  74. package/dist/config/manager.js.map +1 -0
  75. package/dist/config/model.d.ts +334 -0
  76. package/dist/config/model.js +2 -0
  77. package/dist/config/model.js.map +1 -0
  78. package/dist/config/normalize.d.ts +20 -0
  79. package/dist/config/normalize.js +200 -0
  80. package/dist/config/normalize.js.map +1 -0
  81. package/dist/config/parameters.d.ts +37 -0
  82. package/dist/config/parameters.js +71 -0
  83. package/dist/config/parameters.js.map +1 -0
  84. package/dist/config/public.d.ts +6 -0
  85. package/dist/config/public.js +18 -0
  86. package/dist/config/public.js.map +1 -0
  87. package/dist/config/schemas.d.ts +538 -0
  88. package/dist/config/schemas.js +321 -0
  89. package/dist/config/schemas.js.map +1 -0
  90. package/dist/config/snapshot.d.ts +38 -0
  91. package/dist/config/snapshot.js +57 -0
  92. package/dist/config/snapshot.js.map +1 -0
  93. package/dist/config/validate.d.ts +33 -0
  94. package/dist/config/validate.js +346 -0
  95. package/dist/config/validate.js.map +1 -0
  96. package/dist/core/clock.d.ts +59 -0
  97. package/dist/core/clock.js +133 -0
  98. package/dist/core/clock.js.map +1 -0
  99. package/dist/core/duration.d.ts +19 -0
  100. package/dist/core/duration.js +93 -0
  101. package/dist/core/duration.js.map +1 -0
  102. package/dist/core/errors.d.ts +62 -0
  103. package/dist/core/errors.js +72 -0
  104. package/dist/core/errors.js.map +1 -0
  105. package/dist/core/ids.d.ts +57 -0
  106. package/dist/core/ids.js +88 -0
  107. package/dist/core/ids.js.map +1 -0
  108. package/dist/core/index.d.ts +13 -0
  109. package/dist/core/index.js +14 -0
  110. package/dist/core/index.js.map +1 -0
  111. package/dist/core/logger.d.ts +100 -0
  112. package/dist/core/logger.js +207 -0
  113. package/dist/core/logger.js.map +1 -0
  114. package/dist/core/paths.d.ts +84 -0
  115. package/dist/core/paths.js +138 -0
  116. package/dist/core/paths.js.map +1 -0
  117. package/dist/core/template.d.ts +136 -0
  118. package/dist/core/template.js +261 -0
  119. package/dist/core/template.js.map +1 -0
  120. package/dist/core/types.d.ts +544 -0
  121. package/dist/core/types.js +172 -0
  122. package/dist/core/types.js.map +1 -0
  123. package/dist/core/worker-protocol.d.ts +102 -0
  124. package/dist/core/worker-protocol.js +75 -0
  125. package/dist/core/worker-protocol.js.map +1 -0
  126. package/dist/executors/classify.d.ts +25 -0
  127. package/dist/executors/classify.js +54 -0
  128. package/dist/executors/classify.js.map +1 -0
  129. package/dist/executors/dispatcher.d.ts +35 -0
  130. package/dist/executors/dispatcher.js +68 -0
  131. package/dist/executors/dispatcher.js.map +1 -0
  132. package/dist/executors/env.d.ts +43 -0
  133. package/dist/executors/env.js +66 -0
  134. package/dist/executors/env.js.map +1 -0
  135. package/dist/executors/event-parser.d.ts +41 -0
  136. package/dist/executors/event-parser.js +106 -0
  137. package/dist/executors/event-parser.js.map +1 -0
  138. package/dist/executors/index.d.ts +12 -0
  139. package/dist/executors/index.js +13 -0
  140. package/dist/executors/index.js.map +1 -0
  141. package/dist/executors/log-capture.d.ts +57 -0
  142. package/dist/executors/log-capture.js +155 -0
  143. package/dist/executors/log-capture.js.map +1 -0
  144. package/dist/executors/process-identity.d.ts +124 -0
  145. package/dist/executors/process-identity.js +283 -0
  146. package/dist/executors/process-identity.js.map +1 -0
  147. package/dist/executors/shell-executor.d.ts +35 -0
  148. package/dist/executors/shell-executor.js +478 -0
  149. package/dist/executors/shell-executor.js.map +1 -0
  150. package/dist/executors/stream-redactor.d.ts +40 -0
  151. package/dist/executors/stream-redactor.js +89 -0
  152. package/dist/executors/stream-redactor.js.map +1 -0
  153. package/dist/executors/workspace.d.ts +10 -0
  154. package/dist/executors/workspace.js +47 -0
  155. package/dist/executors/workspace.js.map +1 -0
  156. package/dist/filters/evaluate.d.ts +77 -0
  157. package/dist/filters/evaluate.js +187 -0
  158. package/dist/filters/evaluate.js.map +1 -0
  159. package/dist/filters/fields.d.ts +35 -0
  160. package/dist/filters/fields.js +75 -0
  161. package/dist/filters/fields.js.map +1 -0
  162. package/dist/filters/index.d.ts +11 -0
  163. package/dist/filters/index.js +12 -0
  164. package/dist/filters/index.js.map +1 -0
  165. package/dist/filters/iso-date.d.ts +10 -0
  166. package/dist/filters/iso-date.js +42 -0
  167. package/dist/filters/iso-date.js.map +1 -0
  168. package/dist/filters/predicate.d.ts +24 -0
  169. package/dist/filters/predicate.js +178 -0
  170. package/dist/filters/predicate.js.map +1 -0
  171. package/dist/filters/priority.d.ts +51 -0
  172. package/dist/filters/priority.js +91 -0
  173. package/dist/filters/priority.js.map +1 -0
  174. package/dist/filters/pushdown.d.ts +12 -0
  175. package/dist/filters/pushdown.js +52 -0
  176. package/dist/filters/pushdown.js.map +1 -0
  177. package/dist/filters/shell-check.d.ts +110 -0
  178. package/dist/filters/shell-check.js +304 -0
  179. package/dist/filters/shell-check.js.map +1 -0
  180. package/dist/identities/github-app.d.ts +55 -0
  181. package/dist/identities/github-app.js +160 -0
  182. package/dist/identities/github-app.js.map +1 -0
  183. package/dist/identities/index.d.ts +6 -0
  184. package/dist/identities/index.js +7 -0
  185. package/dist/identities/index.js.map +1 -0
  186. package/dist/identities/jwt.d.ts +24 -0
  187. package/dist/identities/jwt.js +56 -0
  188. package/dist/identities/jwt.js.map +1 -0
  189. package/dist/lifecycle/context.d.ts +106 -0
  190. package/dist/lifecycle/context.js +170 -0
  191. package/dist/lifecycle/context.js.map +1 -0
  192. package/dist/lifecycle/engine.d.ts +185 -0
  193. package/dist/lifecycle/engine.js +551 -0
  194. package/dist/lifecycle/engine.js.map +1 -0
  195. package/dist/lifecycle/errors.d.ts +48 -0
  196. package/dist/lifecycle/errors.js +71 -0
  197. package/dist/lifecycle/errors.js.map +1 -0
  198. package/dist/lifecycle/index.d.ts +9 -0
  199. package/dist/lifecycle/index.js +9 -0
  200. package/dist/lifecycle/index.js.map +1 -0
  201. package/dist/lifecycle/performers.d.ts +66 -0
  202. package/dist/lifecycle/performers.js +179 -0
  203. package/dist/lifecycle/performers.js.map +1 -0
  204. package/dist/notifications/index.d.ts +6 -0
  205. package/dist/notifications/index.js +7 -0
  206. package/dist/notifications/index.js.map +1 -0
  207. package/dist/notifications/service.d.ts +115 -0
  208. package/dist/notifications/service.js +364 -0
  209. package/dist/notifications/service.js.map +1 -0
  210. package/dist/persistence/actions.d.ts +101 -0
  211. package/dist/persistence/actions.js +196 -0
  212. package/dist/persistence/actions.js.map +1 -0
  213. package/dist/persistence/blocks.d.ts +85 -0
  214. package/dist/persistence/blocks.js +140 -0
  215. package/dist/persistence/blocks.js.map +1 -0
  216. package/dist/persistence/cron-firings.d.ts +55 -0
  217. package/dist/persistence/cron-firings.js +70 -0
  218. package/dist/persistence/cron-firings.js.map +1 -0
  219. package/dist/persistence/database.d.ts +60 -0
  220. package/dist/persistence/database.js +124 -0
  221. package/dist/persistence/database.js.map +1 -0
  222. package/dist/persistence/errors.d.ts +39 -0
  223. package/dist/persistence/errors.js +67 -0
  224. package/dist/persistence/errors.js.map +1 -0
  225. package/dist/persistence/events.d.ts +72 -0
  226. package/dist/persistence/events.js +83 -0
  227. package/dist/persistence/events.js.map +1 -0
  228. package/dist/persistence/index.d.ts +18 -0
  229. package/dist/persistence/index.js +19 -0
  230. package/dist/persistence/index.js.map +1 -0
  231. package/dist/persistence/instance-lock.d.ts +26 -0
  232. package/dist/persistence/instance-lock.js +117 -0
  233. package/dist/persistence/instance-lock.js.map +1 -0
  234. package/dist/persistence/lock-keys.d.ts +16 -0
  235. package/dist/persistence/lock-keys.js +41 -0
  236. package/dist/persistence/lock-keys.js.map +1 -0
  237. package/dist/persistence/notifications.d.ts +113 -0
  238. package/dist/persistence/notifications.js +213 -0
  239. package/dist/persistence/notifications.js.map +1 -0
  240. package/dist/persistence/persistence.d.ts +46 -0
  241. package/dist/persistence/persistence.js +42 -0
  242. package/dist/persistence/persistence.js.map +1 -0
  243. package/dist/persistence/retention.d.ts +46 -0
  244. package/dist/persistence/retention.js +68 -0
  245. package/dist/persistence/retention.js.map +1 -0
  246. package/dist/persistence/runs.d.ts +215 -0
  247. package/dist/persistence/runs.js +417 -0
  248. package/dist/persistence/runs.js.map +1 -0
  249. package/dist/persistence/schema.d.ts +16 -0
  250. package/dist/persistence/schema.js +183 -0
  251. package/dist/persistence/schema.js.map +1 -0
  252. package/dist/persistence/sqlite.d.ts +49 -0
  253. package/dist/persistence/sqlite.js +131 -0
  254. package/dist/persistence/sqlite.js.map +1 -0
  255. package/dist/runs/controller.d.ts +307 -0
  256. package/dist/runs/controller.js +1078 -0
  257. package/dist/runs/controller.js.map +1 -0
  258. package/dist/runs/errors.d.ts +20 -0
  259. package/dist/runs/errors.js +26 -0
  260. package/dist/runs/errors.js.map +1 -0
  261. package/dist/runs/event-bus.d.ts +106 -0
  262. package/dist/runs/event-bus.js +105 -0
  263. package/dist/runs/event-bus.js.map +1 -0
  264. package/dist/runs/execution.d.ts +39 -0
  265. package/dist/runs/execution.js +146 -0
  266. package/dist/runs/execution.js.map +1 -0
  267. package/dist/runs/index.d.ts +12 -0
  268. package/dist/runs/index.js +13 -0
  269. package/dist/runs/index.js.map +1 -0
  270. package/dist/runs/retention.d.ts +64 -0
  271. package/dist/runs/retention.js +232 -0
  272. package/dist/runs/retention.js.map +1 -0
  273. package/dist/runs/workspace.d.ts +20 -0
  274. package/dist/runs/workspace.js +51 -0
  275. package/dist/runs/workspace.js.map +1 -0
  276. package/dist/scheduler/checks.d.ts +41 -0
  277. package/dist/scheduler/checks.js +111 -0
  278. package/dist/scheduler/checks.js.map +1 -0
  279. package/dist/scheduler/cron.d.ts +32 -0
  280. package/dist/scheduler/cron.js +83 -0
  281. package/dist/scheduler/cron.js.map +1 -0
  282. package/dist/scheduler/dry-run.d.ts +42 -0
  283. package/dist/scheduler/dry-run.js +167 -0
  284. package/dist/scheduler/dry-run.js.map +1 -0
  285. package/dist/scheduler/errors.d.ts +22 -0
  286. package/dist/scheduler/errors.js +22 -0
  287. package/dist/scheduler/errors.js.map +1 -0
  288. package/dist/scheduler/format.d.ts +3 -0
  289. package/dist/scheduler/format.js +73 -0
  290. package/dist/scheduler/format.js.map +1 -0
  291. package/dist/scheduler/index.d.ts +13 -0
  292. package/dist/scheduler/index.js +14 -0
  293. package/dist/scheduler/index.js.map +1 -0
  294. package/dist/scheduler/planner.d.ts +88 -0
  295. package/dist/scheduler/planner.js +255 -0
  296. package/dist/scheduler/planner.js.map +1 -0
  297. package/dist/scheduler/scheduler.d.ts +160 -0
  298. package/dist/scheduler/scheduler.js +680 -0
  299. package/dist/scheduler/scheduler.js.map +1 -0
  300. package/dist/scheduler/state.d.ts +26 -0
  301. package/dist/scheduler/state.js +25 -0
  302. package/dist/scheduler/state.js.map +1 -0
  303. package/dist/scheduler/types.d.ts +197 -0
  304. package/dist/scheduler/types.js +3 -0
  305. package/dist/scheduler/types.js.map +1 -0
  306. package/dist/service/index.d.ts +6 -0
  307. package/dist/service/index.js +7 -0
  308. package/dist/service/index.js.map +1 -0
  309. package/dist/service/install.d.ts +93 -0
  310. package/dist/service/install.js +250 -0
  311. package/dist/service/install.js.map +1 -0
  312. package/dist/service/unit.d.ts +50 -0
  313. package/dist/service/unit.js +171 -0
  314. package/dist/service/unit.js.map +1 -0
  315. package/dist/sources/github/adapter.d.ts +99 -0
  316. package/dist/sources/github/adapter.js +336 -0
  317. package/dist/sources/github/adapter.js.map +1 -0
  318. package/dist/sources/github/fields.d.ts +8 -0
  319. package/dist/sources/github/fields.js +72 -0
  320. package/dist/sources/github/fields.js.map +1 -0
  321. package/dist/sources/github/http.d.ts +100 -0
  322. package/dist/sources/github/http.js +288 -0
  323. package/dist/sources/github/http.js.map +1 -0
  324. package/dist/sources/github/index.d.ts +6 -0
  325. package/dist/sources/github/index.js +7 -0
  326. package/dist/sources/github/index.js.map +1 -0
  327. package/dist/sources/github/pushdown.d.ts +14 -0
  328. package/dist/sources/github/pushdown.js +47 -0
  329. package/dist/sources/github/pushdown.js.map +1 -0
  330. package/dist/sources/github/refs.d.ts +17 -0
  331. package/dist/sources/github/refs.js +61 -0
  332. package/dist/sources/github/refs.js.map +1 -0
  333. package/dist/sources/index.d.ts +6 -0
  334. package/dist/sources/index.js +7 -0
  335. package/dist/sources/index.js.map +1 -0
  336. package/dist/ui/index.d.ts +12 -0
  337. package/dist/ui/index.js +28 -0
  338. package/dist/ui/index.js.map +1 -0
  339. package/dist/ui/public/app.css +239 -0
  340. package/dist/ui/public/favicon.svg +1 -0
  341. package/dist/ui/public/index.html +27 -0
  342. package/dist/ui/public/js/client/api.js +68 -0
  343. package/dist/ui/public/js/client/app.js +146 -0
  344. package/dist/ui/public/js/client/dom.js +34 -0
  345. package/dist/ui/public/js/client/page.js +9 -0
  346. package/dist/ui/public/js/client/pages/actions.js +35 -0
  347. package/dist/ui/public/js/client/pages/blocked.js +58 -0
  348. package/dist/ui/public/js/client/pages/config.js +126 -0
  349. package/dist/ui/public/js/client/pages/dashboard.js +175 -0
  350. package/dist/ui/public/js/client/pages/run.js +367 -0
  351. package/dist/ui/public/js/client/pages/runs.js +72 -0
  352. package/dist/ui/public/js/client/pages/views.js +80 -0
  353. package/dist/ui/public/js/client/pages/workflows.js +291 -0
  354. package/dist/ui/public/js/client/types.js +1 -0
  355. package/dist/ui/public/js/client/ui.js +152 -0
  356. package/dist/ui/public/js/shared/dom.js +77 -0
  357. package/dist/ui/public/js/shared/events.js +88 -0
  358. package/dist/ui/public/js/shared/format.js +213 -0
  359. package/dist/ui/public/js/shared/logs.js +136 -0
  360. package/dist/ui/public/js/shared/params.js +90 -0
  361. package/dist/ui/public/js/shared/route.js +36 -0
  362. package/dist/ui/public/js/shared/sort.js +70 -0
  363. package/dist/ui/public/js/shared/sse.js +193 -0
  364. package/dist/ui/public/js/shared/throttle.js +65 -0
  365. package/dist/views/index.d.ts +6 -0
  366. package/dist/views/index.js +7 -0
  367. package/dist/views/index.js.map +1 -0
  368. package/dist/views/service.d.ts +131 -0
  369. package/dist/views/service.js +264 -0
  370. package/dist/views/service.js.map +1 -0
  371. package/docs/api.md +239 -0
  372. package/docs/configuration-reference.md +1785 -0
  373. package/docs/cron-semantics.md +96 -0
  374. package/docs/manual-tests/github-fixture/config.yaml +30 -0
  375. package/docs/manual-tests/github-fixture/helpers.sh +93 -0
  376. package/docs/manual-tests/github-fixture/identities.yaml +18 -0
  377. package/docs/manual-tests/github-fixture/scripts/test-worker.sh +100 -0
  378. package/docs/manual-tests/github-fixture/sources.yaml +13 -0
  379. package/docs/manual-tests/github-fixture/views/dependencies.yaml +17 -0
  380. package/docs/manual-tests/github-fixture/views/needs-maintainer.yaml +17 -0
  381. package/docs/manual-tests/github-fixture/workflows/coder-test.yaml +76 -0
  382. package/docs/manual-tests/github-fixture/workflows/commenter-test.yaml +63 -0
  383. package/docs/manual-tests/github-fixture/workflows/reviewer-test.yaml +60 -0
  384. package/docs/manual-tests/github.md +1308 -0
  385. package/docs/manual-tests/process-supervision.md +64 -0
  386. package/docs/manual-tests/systemd.md +68 -0
  387. package/docs/operations.md +271 -0
  388. package/docs/worker-protocol.md +145 -0
  389. package/examples/config/config.yaml +35 -0
  390. package/examples/config/identities.yaml +18 -0
  391. package/examples/config/sources.yaml +13 -0
  392. package/examples/config/views/needs-maintainer.yaml +15 -0
  393. package/examples/config/workflows/coder-project-a.yaml +86 -0
  394. package/examples/config/workflows/deploy.yaml +15 -0
  395. package/examples/config/workflows/nightly-maintenance.yaml +13 -0
  396. package/package.json +75 -4
@@ -0,0 +1,144 @@
1
+ /**
2
+ * `workflow dry-run <id>` (Spec §19). Never reserves, never starts workers,
3
+ * never runs lifecycle actions or shell filters/conditions.
4
+ *
5
+ * - **Running instance (default):** `POST /api/v1/workflows/<id>/dry-run`
6
+ * against `--url` or the URL from `config.yaml` (includes the live gate:
7
+ * pause/drain/readiness).
8
+ * - **Local fallback** (no instance reachable and `--config-dir` given, or
9
+ * `--local`): loads the configuration, queries the source with the
10
+ * configured GitHub App identity and reads locks/blocks/active runs
11
+ * read-only from the data directory's database (if present). An explicit
12
+ * `--url` never falls back.
13
+ *
14
+ * Exit codes: 0 = dry-run done, 1 = invalid configuration / unknown workflow
15
+ * / source error / API error, 2 = usage error, 3 = `--url` not reachable.
16
+ */
17
+ import { existsSync } from 'node:fs';
18
+ import path from 'node:path';
19
+ import { DatabaseSync } from 'node:sqlite';
20
+ import { dataPaths, errorMessage, systemClock } from '../core/index.js';
21
+ import { ConfigLoadError, ConfigManager, formatConfigIssue } from '../config/index.js';
22
+ import { MIGRATIONS, createRepositories, schemaVersion } from '../persistence/index.js';
23
+ import { dryRunWorkflow, emptyState, formatDryRun, repositoryState } from '../scheduler/index.js';
24
+ import { SourceRegistry } from '../app.js';
25
+ import { ApiClient, ApiResponseError, ApiUnreachableError, EXIT_UNREACHABLE, resolveBaseUrl } from './http-client.js';
26
+ /** Read-only scheduling state from `<dataDir>/adispatchd.sqlite`, if usable. */
27
+ function openState(dataDir, notes) {
28
+ const none = { state: emptyState(), close: () => undefined };
29
+ if (!dataDir) {
30
+ notes.push('no --data-dir given: active runs, locks, blocks and cron history are not considered');
31
+ return none;
32
+ }
33
+ const file = dataPaths(path.resolve(dataDir)).database;
34
+ if (!existsSync(file)) {
35
+ notes.push(`no database at ${file}: active runs, locks, blocks and cron history are not considered`);
36
+ return none;
37
+ }
38
+ let db;
39
+ try {
40
+ db = new DatabaseSync(file, { readOnly: true });
41
+ db.exec('PRAGMA busy_timeout = 5000');
42
+ const expected = Math.max(...MIGRATIONS.map((m) => m.version));
43
+ const actual = schemaVersion(db);
44
+ if (actual !== expected) {
45
+ notes.push(`database schema version ${actual} differs from ${expected}: database not used`);
46
+ db.close();
47
+ return none;
48
+ }
49
+ const repos = createRepositories(db);
50
+ const opened = db;
51
+ return { state: repositoryState(repos), close: () => opened.close() };
52
+ }
53
+ catch (err) {
54
+ db?.close();
55
+ notes.push(`database ${file} not readable (${errorMessage(err)}): active runs, locks and blocks are not considered`);
56
+ return none;
57
+ }
58
+ }
59
+ /** Create the `workflow dry-run` handler. */
60
+ export function createWorkflowDryRunHandler(io, deps = {}) {
61
+ return async (workflowId, opts) => {
62
+ const fallbackNotes = [];
63
+ if (!opts.local) {
64
+ const remote = await dryRunRemote(workflowId, opts, io, deps);
65
+ if (remote.done)
66
+ return remote.code;
67
+ if (!opts.configDir) {
68
+ io.stderr(`workflow dry-run: no running instance at ${remote.url} and no --config-dir for a local dry-run\n`);
69
+ return 2;
70
+ }
71
+ fallbackNotes.push(`no running instance at ${remote.url}: evaluated locally (pause/drain/readiness of an instance not considered)`);
72
+ }
73
+ if (!opts.configDir) {
74
+ io.stderr('workflow dry-run: --config-dir is required for a local dry-run\n');
75
+ return 2;
76
+ }
77
+ const clock = deps.clock ?? systemClock;
78
+ const configDir = path.resolve(opts.configDir);
79
+ const dataDir = path.resolve(opts.dataDir ?? 'data');
80
+ let config;
81
+ try {
82
+ config = await ConfigManager.create({ configDir, dataDir, clock });
83
+ }
84
+ catch (err) {
85
+ if (err instanceof ConfigLoadError) {
86
+ io.stderr(`Configuration in ${configDir} is invalid:\n${err.errors.map((i) => ` ${formatConfigIssue(i)}\n`).join('')}`);
87
+ return 1;
88
+ }
89
+ throw err;
90
+ }
91
+ if (!config.getWorkflow(workflowId)) {
92
+ io.stderr(`workflow dry-run: unknown workflow '${workflowId}'\n`);
93
+ return 1;
94
+ }
95
+ const notes = [...fallbackNotes];
96
+ const { state, close } = openState(opts.dataDir, notes);
97
+ try {
98
+ const sources = new SourceRegistry(config.current, {
99
+ clock,
100
+ ...(deps.fetch ? { fetch: deps.fetch } : {}),
101
+ ...(deps.env ? { env: deps.env } : {}),
102
+ });
103
+ const result = await dryRunWorkflow({ config, sources: (id) => sources.get(id), state, clock, notes }, workflowId);
104
+ io.stdout(opts.json ? `${JSON.stringify(result, null, 2)}\n` : formatDryRun(result));
105
+ return result.source?.error ? 1 : 0;
106
+ }
107
+ finally {
108
+ close();
109
+ }
110
+ };
111
+ }
112
+ /** Try the running instance; `done: false` = not reachable (fall back to local). */
113
+ async function dryRunRemote(workflowId, opts, io, deps) {
114
+ let url;
115
+ try {
116
+ url = (await resolveBaseUrl(opts)).url;
117
+ }
118
+ catch (err) {
119
+ io.stderr(`workflow dry-run: ${errorMessage(err)}\n`);
120
+ return { done: true, code: 2 };
121
+ }
122
+ const api = new ApiClient(url, deps.apiFetch ? { fetch: deps.apiFetch } : {});
123
+ try {
124
+ const { body } = await api.post(`/api/v1/workflows/${encodeURIComponent(workflowId)}/dry-run`);
125
+ io.stdout(opts.json ? `${JSON.stringify(body, null, 2)}\n` : formatDryRun(body));
126
+ return { done: true, code: body.source?.error ? 1 : 0 };
127
+ }
128
+ catch (err) {
129
+ if (err instanceof ApiUnreachableError) {
130
+ if (opts.url) {
131
+ io.stderr(`workflow dry-run: ${err.message}\n`);
132
+ return { done: true, code: EXIT_UNREACHABLE };
133
+ }
134
+ return { done: false, url };
135
+ }
136
+ if (err instanceof ApiResponseError && err.code === 'config_unknown_workflow') {
137
+ io.stderr(`workflow dry-run: unknown workflow '${workflowId}' (instance at ${url})\n`);
138
+ return { done: true, code: 1 };
139
+ }
140
+ io.stderr(`workflow dry-run: ${errorMessage(err)}${err instanceof ApiResponseError ? ` (HTTP ${err.status}, ${err.code})` : ''}\n`);
141
+ return { done: true, code: 1 };
142
+ }
143
+ }
144
+ //# sourceMappingURL=workflow-dry-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-dry-run.js","sourceRoot":"","sources":["../../src/cli/workflow-dry-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Offline checks of field references against the static field catalogue of
3
+ * the adapter type (WI-13): field names (with "did you mean" suggestions),
4
+ * operators per field type, value types, view-only `run.last_*` fields and
5
+ * listing-selector fields such as GitHub `state` that only work at the top
6
+ * level of a filter (pushdown).
7
+ */
8
+ import { type FieldDefinition, type FilterNode } from '../core/index.js';
9
+ /** Static field catalogue per source adapter type. */
10
+ export declare const FIELD_CATALOG: Readonly<Record<string, readonly FieldDefinition[]>>;
11
+ /** Problem with a field reference; `path` is relative to the checked node. */
12
+ export interface FieldIssue {
13
+ path: (string | number)[];
14
+ message: string;
15
+ }
16
+ /** Field catalogue for a context, or `undefined` if the adapter type has none (no checks). */
17
+ export interface FieldContext {
18
+ sourceType: string;
19
+ /** View context: `run.last_*` fields are available. */
20
+ view: boolean;
21
+ }
22
+ /** Closest known name, if reasonably close. */
23
+ export declare function suggestField(name: string, names: readonly string[]): string | undefined;
24
+ /** Check a single field name (view columns, links, sort). */
25
+ export declare function checkFieldName(field: string, ctx: FieldContext): string | undefined;
26
+ /**
27
+ * Check every predicate of `node` against the catalogue of `ctx`.
28
+ * `listing: true` for the main `filter` of a workflow/view (applies the
29
+ * listing-selector rule); `false` for e.g. `item_priority` rules.
30
+ */
31
+ export declare function checkFilterFields(node: FilterNode, ctx: FieldContext, options: {
32
+ listing: boolean;
33
+ }): FieldIssue[];
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Offline checks of field references against the static field catalogue of
3
+ * the adapter type (WI-13): field names (with "did you mean" suggestions),
4
+ * operators per field type, value types, view-only `run.last_*` fields and
5
+ * listing-selector fields such as GitHub `state` that only work at the top
6
+ * level of a filter (pushdown).
7
+ */
8
+ import { VIEW_RUN_FIELDS, isFilterAll, isFilterAny, isFilterNot, } from '../core/index.js';
9
+ import { parseIsoDate } from '../filters/index.js';
10
+ import { GITHUB_FIELD_DEFINITIONS } from '../sources/index.js';
11
+ /** Static field catalogue per source adapter type. */
12
+ export const FIELD_CATALOG = {
13
+ github: GITHUB_FIELD_DEFINITIONS,
14
+ };
15
+ const LISTING_FIELDS = {
16
+ github: { field: 'state', operators: ['equals', 'in'], values: ['open', 'closed'], defaultDescription: 'only open issues/PRs' },
17
+ };
18
+ function definitions(ctx) {
19
+ const base = FIELD_CATALOG[ctx.sourceType];
20
+ if (!base)
21
+ return undefined;
22
+ return ctx.view ? [...base, ...VIEW_RUN_FIELDS] : base;
23
+ }
24
+ function distance(a, b) {
25
+ const prev = Array.from({ length: b.length + 1 }, (_, j) => j);
26
+ for (let i = 1; i <= a.length; i++) {
27
+ let diag = prev[0];
28
+ prev[0] = i;
29
+ for (let j = 1; j <= b.length; j++) {
30
+ const tmp = prev[j];
31
+ prev[j] = Math.min(prev[j] + 1, prev[j - 1] + 1, diag + (a[i - 1] === b[j - 1] ? 0 : 1));
32
+ diag = tmp;
33
+ }
34
+ }
35
+ return prev[b.length];
36
+ }
37
+ /** Closest known name, if reasonably close. */
38
+ export function suggestField(name, names) {
39
+ let best;
40
+ let bestDistance = Infinity;
41
+ for (const candidate of names) {
42
+ const d = distance(name.toLowerCase(), candidate.toLowerCase());
43
+ if (d < bestDistance) {
44
+ best = candidate;
45
+ bestDistance = d;
46
+ }
47
+ }
48
+ return best !== undefined && bestDistance <= Math.max(2, Math.floor(name.length / 3)) ? best : undefined;
49
+ }
50
+ /** Message for an unknown field, or `undefined` if the field exists. */
51
+ function unknownFieldMessage(field, ctx, defs) {
52
+ if (defs.some((d) => d.name === field))
53
+ return undefined;
54
+ if (!ctx.view && VIEW_RUN_FIELDS.some((d) => d.name === field)) {
55
+ return `Field "${field}" is only available in views, not in workflows`;
56
+ }
57
+ const suggestion = suggestField(field, defs.map((d) => d.name));
58
+ const hint = suggestion ? ` (did you mean "${suggestion}"?)` : '';
59
+ return `Unknown field "${field}" for source type ${ctx.sourceType}${hint}`;
60
+ }
61
+ /** Check a single field name (view columns, links, sort). */
62
+ export function checkFieldName(field, ctx) {
63
+ const defs = definitions(ctx);
64
+ return defs ? unknownFieldMessage(field, ctx, defs) : undefined;
65
+ }
66
+ const SCALAR_TYPE = {
67
+ string: 'string',
68
+ number: 'number',
69
+ boolean: 'boolean',
70
+ date: 'string',
71
+ 'string[]': 'string',
72
+ };
73
+ function describeValue(v) {
74
+ return typeof v === 'string' ? `string "${v}"` : v === null ? 'null' : `${typeof v} ${String(v)}`;
75
+ }
76
+ function checkValue(p, def, at, issues) {
77
+ const values = Array.isArray(p.value) ? p.value : [p.value];
78
+ if (p.value === null) {
79
+ if (p.operator !== 'equals' && p.operator !== 'not_equals') {
80
+ issues.push({ path: [...at, 'value'], message: `Operator "${p.operator}" cannot compare with null` });
81
+ }
82
+ return;
83
+ }
84
+ const expected = SCALAR_TYPE[def.type];
85
+ for (const v of values) {
86
+ if (typeof v !== expected) {
87
+ issues.push({
88
+ path: [...at, 'value'],
89
+ message: `Value for field "${def.name}" (type ${def.type}) must be a ${expected}, got ${describeValue(v)}`,
90
+ });
91
+ return;
92
+ }
93
+ if (def.type === 'date' && parseIsoDate(v) === undefined) {
94
+ issues.push({
95
+ path: [...at, 'value'],
96
+ message: `Value "${String(v)}" for date field "${def.name}" is not an ISO-8601 date (YYYY-MM-DD or YYYY-MM-DDTHH:MM[:SS][Z|±HH:MM])`,
97
+ });
98
+ return;
99
+ }
100
+ }
101
+ }
102
+ function checkListing(p, listing, topLevel, at, issues) {
103
+ const selector = `${listing.field} ${listing.operators.join('/')} ${listing.values.join('|')}`;
104
+ if (!topLevel) {
105
+ issues.push({
106
+ path: [...at, 'field'],
107
+ message: `"${listing.field}" only works at the top level of the filter (directly or inside top-level "all"): ` +
108
+ `the source lists ${listing.defaultDescription} unless the top-level filter selects others (${selector}), ` +
109
+ `so under "any"/"not" it would silently never see them`,
110
+ });
111
+ return;
112
+ }
113
+ if (!listing.operators.includes(p.operator)) {
114
+ issues.push({
115
+ path: [...at, 'operator'],
116
+ message: `"${listing.field}" must use ${listing.operators.map((o) => `"${o}"`).join(' or ')}: only these select which items are listed (otherwise ${listing.defaultDescription} are seen)`,
117
+ });
118
+ return;
119
+ }
120
+ const values = Array.isArray(p.value) ? p.value : [p.value];
121
+ const bad = values.find((v) => typeof v !== 'string' || !listing.values.includes(v));
122
+ if (bad !== undefined) {
123
+ issues.push({
124
+ path: [...at, 'value'],
125
+ message: `"${listing.field}" values must be ${listing.values.map((v) => `"${v}"`).join(' or ')}, got ${describeValue(bad)}`,
126
+ });
127
+ }
128
+ }
129
+ /**
130
+ * Check every predicate of `node` against the catalogue of `ctx`.
131
+ * `listing: true` for the main `filter` of a workflow/view (applies the
132
+ * listing-selector rule); `false` for e.g. `item_priority` rules.
133
+ */
134
+ export function checkFilterFields(node, ctx, options) {
135
+ const defs = definitions(ctx);
136
+ if (!defs)
137
+ return [];
138
+ const listing = options.listing ? LISTING_FIELDS[ctx.sourceType] : undefined;
139
+ const issues = [];
140
+ const visit = (n, at, topLevel) => {
141
+ if (isFilterAll(n))
142
+ return n.all.forEach((c, i) => visit(c, [...at, 'all', i], topLevel));
143
+ if (isFilterAny(n))
144
+ return n.any.forEach((c, i) => visit(c, [...at, 'any', i], false));
145
+ if (isFilterNot(n))
146
+ return visit(n.not, [...at, 'not'], false);
147
+ const p = n;
148
+ const unknown = unknownFieldMessage(p.field, ctx, defs);
149
+ if (unknown) {
150
+ issues.push({ path: [...at, 'field'], message: unknown });
151
+ return;
152
+ }
153
+ const def = defs.find((d) => d.name === p.field);
154
+ if (!def.operators.includes(p.operator)) {
155
+ issues.push({
156
+ path: [...at, 'operator'],
157
+ message: `Operator "${p.operator}" is not supported for field "${p.field}" (type ${def.type}); allowed: ${def.operators.join(', ')}`,
158
+ });
159
+ return;
160
+ }
161
+ if (listing && p.field === listing.field) {
162
+ const before = issues.length;
163
+ checkListing(p, listing, topLevel, at, issues);
164
+ if (issues.length > before)
165
+ return;
166
+ }
167
+ checkValue(p, def, at, issues);
168
+ };
169
+ visit(node, [], true);
170
+ return issues;
171
+ }
172
+ //# sourceMappingURL=field-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-catalog.js","sourceRoot":"","sources":["../../src/config/field-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,eAAe,EACf,WAAW,EACX,WAAW,EACX,WAAW,GAKZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,sDAAsD;AACtD,MAAM,CAAC,MAAM,aAAa,GAAyD;IACjF,MAAM,EAAE,wBAAwB;CACjC,CAAC;AAeF,MAAM,cAAc,GAA2C;IAC7D,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,kBAAkB,EAAE,sBAAsB,EAAE;CAChI,CAAC;AAeF,SAAS,WAAW,CAAC,GAAiB;IACpC,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzD,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,CAAW,CAAC;QAC7B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAW,CAAC;YAC9B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAE,IAAI,CAAC,CAAC,CAAY,GAAG,CAAC,EAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAY,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjH,IAAI,GAAG,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAW,CAAC;AAClC,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAwB;IACjE,IAAI,IAAwB,CAAC;IAC7B,IAAI,YAAY,GAAG,QAAQ,CAAC;IAC5B,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC;YACrB,IAAI,GAAG,SAAS,CAAC;YACjB,YAAY,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,KAAK,SAAS,IAAI,YAAY,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3G,CAAC;AAED,wEAAwE;AACxE,SAAS,mBAAmB,CAAC,KAAa,EAAE,GAAiB,EAAE,IAAgC;IAC7F,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzD,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,UAAU,KAAK,gDAAgD,CAAC;IACzE,CAAC;IACD,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,mBAAmB,UAAU,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO,kBAAkB,KAAK,qBAAqB,GAAG,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC;AAC7E,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,GAAiB;IAC7D,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClE,CAAC;AAED,MAAM,WAAW,GAAuD;IACtE,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,QAAQ;CACrB,CAAC;AAEF,SAAS,aAAa,CAAC,CAAU;IAC/B,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AACpG,CAAC;AAED,SAAS,UAAU,CAAC,CAAkB,EAAE,GAAoB,EAAE,EAAuB,EAAE,MAAoB;IACzG,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAA4B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpF,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC3D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,QAAQ,4BAA4B,EAAE,CAAC,CAAC;QACxG,CAAC;QACD,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC;gBACtB,OAAO,EAAE,oBAAoB,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,IAAI,eAAe,QAAQ,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE;aAC3G,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC;gBACtB,OAAO,EAAE,UAAU,MAAM,CAAC,CAAC,CAAC,qBAAqB,GAAG,CAAC,IAAI,2EAA2E;aACrI,CAAC,CAAC;YACH,OAAO;QACT,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CACnB,CAAkB,EAClB,OAAqB,EACrB,QAAiB,EACjB,EAAuB,EACvB,MAAoB;IAEpB,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAC/F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC;YACtB,OAAO,EACL,IAAI,OAAO,CAAC,KAAK,oFAAoF;gBACrG,oBAAoB,OAAO,CAAC,kBAAkB,gDAAgD,QAAQ,KAAK;gBAC3G,uDAAuD;SAC1D,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;YACzB,OAAO,EAAE,IAAI,OAAO,CAAC,KAAK,cAAc,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,yDAAyD,OAAO,CAAC,kBAAkB,YAAY;SAC3L,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAA4B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC;YACtB,OAAO,EAAE,IAAI,OAAO,CAAC,KAAK,oBAAoB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE;SAC5H,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAgB,EAAE,GAAiB,EAAE,OAA6B;IAClG,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7E,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,CAAC,CAAa,EAAE,EAAuB,EAAE,QAAiB,EAAQ,EAAE;QAChF,IAAI,WAAW,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC1F,IAAI,WAAW,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QACvF,IAAI,WAAW,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAoB,CAAC;QAC/B,MAAM,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,CAAoB,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;gBACzB,OAAO,EAAE,aAAa,CAAC,CAAC,QAAQ,iCAAiC,CAAC,CAAC,KAAK,WAAW,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aACrI,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC7B,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/C,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM;gBAAE,OAAO;QACrC,CAAC;QACD,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Structural validation of the declarative filter AST (Spec §6) as it appears
3
+ * in YAML. Hand-written instead of a zod union so that errors point at the
4
+ * exact offending node (`filter.all[1].operator`) with a precise message.
5
+ */
6
+ import { z } from 'zod';
7
+ /** Problem found in a filter node. `path` is relative to the filter root. */
8
+ export interface FilterIssue {
9
+ path: (string | number)[];
10
+ message: string;
11
+ }
12
+ /** Validate a filter node; returns all problems (empty = valid). */
13
+ export declare function validateFilterNode(node: unknown, path?: (string | number)[]): FilterIssue[];
14
+ /** zod schema accepting a YAML filter AST and producing a clean {@link FilterNode}. */
15
+ export declare const filterNodeSchema: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("../core/types.js").FilterAll | import("../core/types.js").FilterAny | import("../core/types.js").FilterNot | import("../core/types.js").FilterPredicate, unknown>>;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Structural validation of the declarative filter AST (Spec §6) as it appears
3
+ * in YAML. Hand-written instead of a zod union so that errors point at the
4
+ * exact offending node (`filter.all[1].operator`) with a precise message.
5
+ */
6
+ import { z } from 'zod';
7
+ import { FILTER_OPERATORS } from '../core/index.js';
8
+ const OPERATOR_SET = new Set(FILTER_OPERATORS);
9
+ function isPlainObject(value) {
10
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
11
+ }
12
+ function isScalar(value) {
13
+ return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
14
+ }
15
+ function checkValue(operator, value, path, issues) {
16
+ if (operator === 'in') {
17
+ if (!Array.isArray(value) || value.length === 0 || !value.every(isScalar)) {
18
+ issues.push({ path, message: 'Operator "in" requires a non-empty list of strings, numbers or booleans' });
19
+ }
20
+ return;
21
+ }
22
+ if (operator === 'greater_than' || operator === 'less_than') {
23
+ if (typeof value !== 'number' && typeof value !== 'string') {
24
+ issues.push({ path, message: `Operator "${operator}" requires a number or string (date) value` });
25
+ }
26
+ return;
27
+ }
28
+ if (value !== null && !isScalar(value)) {
29
+ issues.push({ path, message: `Operator "${operator}" requires a scalar value (string, number, boolean or null)` });
30
+ }
31
+ }
32
+ /** Validate a filter node; returns all problems (empty = valid). */
33
+ export function validateFilterNode(node, path = []) {
34
+ const issues = [];
35
+ visit(node, path, issues);
36
+ return issues;
37
+ }
38
+ function visit(node, path, issues) {
39
+ if (!isPlainObject(node)) {
40
+ issues.push({ path, message: 'Filter node must be a mapping (all / any / not / {field, operator, value})' });
41
+ return;
42
+ }
43
+ const keys = Object.keys(node);
44
+ for (const combinator of ['all', 'any']) {
45
+ if (combinator in node) {
46
+ if (keys.length !== 1) {
47
+ issues.push({ path, message: `"${combinator}" must be the only key of its filter node` });
48
+ return;
49
+ }
50
+ const children = node[combinator];
51
+ if (!Array.isArray(children)) {
52
+ issues.push({ path: [...path, combinator], message: `"${combinator}" must be a list of filter nodes` });
53
+ return;
54
+ }
55
+ children.forEach((child, i) => visit(child, [...path, combinator, i], issues));
56
+ return;
57
+ }
58
+ }
59
+ if ('not' in node) {
60
+ if (keys.length !== 1) {
61
+ issues.push({ path, message: '"not" must be the only key of its filter node' });
62
+ return;
63
+ }
64
+ visit(node.not, [...path, 'not'], issues);
65
+ return;
66
+ }
67
+ const unknown = keys.filter((k) => k !== 'field' && k !== 'operator' && k !== 'value');
68
+ if (unknown.length > 0) {
69
+ issues.push({ path, message: `Unknown filter key(s): ${unknown.map((k) => `"${k}"`).join(', ')}` });
70
+ }
71
+ if (typeof node.field !== 'string' || node.field.trim() === '') {
72
+ issues.push({ path: [...path, 'field'], message: 'Predicate requires a non-empty "field"' });
73
+ }
74
+ if (typeof node.operator !== 'string' || !OPERATOR_SET.has(node.operator)) {
75
+ issues.push({
76
+ path: [...path, 'operator'],
77
+ message: `Predicate requires "operator", one of: ${FILTER_OPERATORS.join(', ')}`,
78
+ });
79
+ return;
80
+ }
81
+ if (!('value' in node)) {
82
+ issues.push({ path: [...path, 'value'], message: 'Predicate requires a "value" (use null explicitly if intended)' });
83
+ return;
84
+ }
85
+ checkValue(node.operator, node.value, [...path, 'value'], issues);
86
+ }
87
+ function toFilterNode(node) {
88
+ if ('all' in node)
89
+ return { all: node.all.map(toFilterNode) };
90
+ if ('any' in node)
91
+ return { any: node.any.map(toFilterNode) };
92
+ if ('not' in node)
93
+ return { not: toFilterNode(node.not) };
94
+ const value = node.value;
95
+ return {
96
+ field: node.field.trim(),
97
+ operator: node.operator,
98
+ value: Array.isArray(value) ? [...value] : value,
99
+ };
100
+ }
101
+ /** zod schema accepting a YAML filter AST and producing a clean {@link FilterNode}. */
102
+ export const filterNodeSchema = z
103
+ .unknown()
104
+ .superRefine((value, ctx) => {
105
+ for (const issue of validateFilterNode(value)) {
106
+ ctx.addIssue({ code: 'custom', message: issue.message, path: issue.path });
107
+ }
108
+ })
109
+ .transform((value) => toFilterNode(value));
110
+ //# sourceMappingURL=filter-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-schema.js","sourceRoot":"","sources":["../../src/config/filter-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Component `config` – public API (WI-02): YAML schemas, loader, semantic
3
+ * validation, ConfigManager with reload/overrides, workflow snapshots and
4
+ * manual-start parameter validation. Other components import from this
5
+ * module only.
6
+ */
7
+ export * from './model.js';
8
+ export { formatConfigIssue } from './issues.js';
9
+ export { loadConfig, MAX_CONFIG_FILE_BYTES, VIEWS_DIR, WORKFLOWS_DIR, type LoadConfigOptions, type LoadConfigResult, } from './loader.js';
10
+ export { CONFIG_FILE, IDENTITIES_FILE, RESERVED_ENV_PREFIX, SOURCES_FILE, cronError, isValidTimeZone } from './validate.js';
11
+ export { DEFAULT_WORKING_DIRECTORY, DEFAULTS } from './schemas.js';
12
+ export { ConfigLoadError, ConfigManager, diffWorkflows, type ConfigChangeEvent, type ConfigChangeListener, type ConfigDiff, type ConfigLoader, type ConfigManagerOptions, type EffectiveWorkflow, type GlobalOverrides, type ReloadResult, type WorkflowOverrides, } from './manager.js';
13
+ export { snapshotWorkflow, UnknownWorkflowError, WORKFLOW_SNAPSHOT_VERSION, workflowIdentityRefs, type WorkflowSnapshot, } from './snapshot.js';
14
+ export { automaticParameterValues, validateParameters, validateWorkflowParameters, type ParameterIssue, type ParameterValidationResult, } from './parameters.js';
15
+ export { toPublicConfig } from './public.js';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Component `config` – public API (WI-02): YAML schemas, loader, semantic
3
+ * validation, ConfigManager with reload/overrides, workflow snapshots and
4
+ * manual-start parameter validation. Other components import from this
5
+ * module only.
6
+ */
7
+ export * from './model.js';
8
+ export { formatConfigIssue } from './issues.js';
9
+ export { loadConfig, MAX_CONFIG_FILE_BYTES, VIEWS_DIR, WORKFLOWS_DIR, } from './loader.js';
10
+ export { CONFIG_FILE, IDENTITIES_FILE, RESERVED_ENV_PREFIX, SOURCES_FILE, cronError, isValidTimeZone } from './validate.js';
11
+ export { DEFAULT_WORKING_DIRECTORY, DEFAULTS } from './schemas.js';
12
+ export { ConfigLoadError, ConfigManager, diffWorkflows, } from './manager.js';
13
+ export { snapshotWorkflow, UnknownWorkflowError, WORKFLOW_SNAPSHOT_VERSION, workflowIdentityRefs, } from './snapshot.js';
14
+ export { automaticParameterValues, validateParameters, validateWorkflowParameters, } from './parameters.js';
15
+ export { toPublicConfig } from './public.js';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,SAAS,EACT,aAAa,GAGd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5H,OAAO,EAAE,yBAAyB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,GAUd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EACzB,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,0BAA0B,GAG3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Collecting and formatting configuration issues.
3
+ */
4
+ import type { ConfigIssue, ConfigIssueSeverity } from './model.js';
5
+ /** Path segments inside a YAML document. */
6
+ export type IssuePath = readonly (string | number)[];
7
+ /** Issue before line resolution. */
8
+ export interface PendingIssue {
9
+ severity: ConfigIssueSeverity;
10
+ file: string;
11
+ path: IssuePath;
12
+ message: string;
13
+ line?: number;
14
+ }
15
+ /** Mutable collector used during one load. */
16
+ export declare class IssueCollector {
17
+ readonly items: PendingIssue[];
18
+ error(file: string, path: IssuePath, message: string, line?: number): void;
19
+ warning(file: string, path: IssuePath, message: string, line?: number): void;
20
+ get hasErrors(): boolean;
21
+ }
22
+ /** Format path segments as `a.b[1].c`. */
23
+ export declare function formatIssuePath(path: IssuePath): string;
24
+ /** Human-readable single line: `workflows/coder.yaml:12: execute.timeout: message`. */
25
+ export declare function formatConfigIssue(issue: ConfigIssue): string;
26
+ /** Stable ordering: by file, then line, then path. */
27
+ export declare function sortIssues(issues: ConfigIssue[]): ConfigIssue[];
@@ -0,0 +1,37 @@
1
+ /** Mutable collector used during one load. */
2
+ export class IssueCollector {
3
+ items = [];
4
+ error(file, path, message, line) {
5
+ this.items.push({ severity: 'error', file, path, message, ...(line !== undefined ? { line } : {}) });
6
+ }
7
+ warning(file, path, message, line) {
8
+ this.items.push({ severity: 'warning', file, path, message, ...(line !== undefined ? { line } : {}) });
9
+ }
10
+ get hasErrors() {
11
+ return this.items.some((i) => i.severity === 'error');
12
+ }
13
+ }
14
+ /** Format path segments as `a.b[1].c`. */
15
+ export function formatIssuePath(path) {
16
+ let out = '';
17
+ for (const segment of path) {
18
+ if (typeof segment === 'number')
19
+ out += `[${segment}]`;
20
+ else
21
+ out += out === '' ? segment : `.${segment}`;
22
+ }
23
+ return out;
24
+ }
25
+ /** Human-readable single line: `workflows/coder.yaml:12: execute.timeout: message`. */
26
+ export function formatConfigIssue(issue) {
27
+ const location = issue.line !== undefined ? `${issue.file}:${issue.line}` : issue.file;
28
+ const prefix = issue.severity === 'warning' ? 'warning: ' : '';
29
+ return issue.path ? `${location}: ${prefix}${issue.path}: ${issue.message}` : `${location}: ${prefix}${issue.message}`;
30
+ }
31
+ /** Stable ordering: by file, then line, then path. */
32
+ export function sortIssues(issues) {
33
+ return [...issues].sort((a, b) => a.file.localeCompare(b.file) ||
34
+ (a.line ?? Number.MAX_SAFE_INTEGER) - (b.line ?? Number.MAX_SAFE_INTEGER) ||
35
+ a.path.localeCompare(b.path));
36
+ }
37
+ //# sourceMappingURL=issues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issues.js","sourceRoot":"","sources":["../../src/config/issues.ts"],"names":[],"mappings":"AAiBA,8CAA8C;AAC9C,MAAM,OAAO,cAAc;IAChB,KAAK,GAAmB,EAAE,CAAC;IAEpC,KAAK,CAAC,IAAY,EAAE,IAAe,EAAE,OAAe,EAAE,IAAa;QACjE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;IAED,OAAO,CAAC,IAAY,EAAE,IAAe,EAAE,OAAe,EAAE,IAAa;QACnE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IACxD,CAAC;CACF;AAED,0CAA0C;AAC1C,MAAM,UAAU,eAAe,CAAC,IAAe;IAC7C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,OAAO,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC;;YAClD,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,KAAkB;IAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IACvF,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;AACzH,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,MAAqB;IAC9C,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CACrB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5B,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,gBAAgB,CAAC;QACzE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAC/B,CAAC;AACJ,CAAC"}