@pikku/core 0.12.107 → 0.12.111

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 (588) hide show
  1. package/CHANGELOG.md +344 -0
  2. package/dist/analytics/analytics.d.ts +6 -0
  3. package/dist/analytics/analytics.js +58 -0
  4. package/dist/analytics/analytics.types.d.ts +156 -0
  5. package/dist/analytics/analytics.types.js +1 -0
  6. package/dist/analytics/anonymous-analytics-identity.d.ts +23 -0
  7. package/dist/analytics/anonymous-analytics-identity.js +27 -0
  8. package/dist/analytics/compose-analytics-identity.d.ts +14 -0
  9. package/dist/analytics/compose-analytics-identity.js +33 -0
  10. package/dist/analytics/cookie-analytics-identity.d.ts +24 -0
  11. package/dist/analytics/cookie-analytics-identity.js +37 -0
  12. package/dist/analytics/define-analytics-events.d.ts +22 -0
  13. package/dist/analytics/define-analytics-events.js +9 -0
  14. package/dist/analytics/fan-out-analytics.d.ts +15 -0
  15. package/dist/analytics/fan-out-analytics.js +36 -0
  16. package/dist/analytics/index.d.ts +13 -0
  17. package/dist/analytics/index.js +8 -0
  18. package/dist/analytics/logger-analytics-service.d.ts +14 -0
  19. package/dist/analytics/logger-analytics-service.js +23 -0
  20. package/dist/analytics/mint-cookie.d.ts +44 -0
  21. package/dist/analytics/mint-cookie.js +55 -0
  22. package/dist/errors/errors.d.ts +7 -0
  23. package/dist/errors/errors.js +17 -0
  24. package/dist/function/function-meta.types.d.ts +2 -0
  25. package/dist/function/function-runner.js +29 -0
  26. package/dist/function/functions.types.d.ts +22 -3
  27. package/dist/middleware/auth-apikey.d.ts +1 -1
  28. package/dist/pikku-state.d.ts +1 -1
  29. package/dist/scopes.d.ts +11 -0
  30. package/dist/scopes.js +17 -0
  31. package/dist/services/credential-wire-service.d.ts +1 -1
  32. package/dist/services/feature-flag-service.d.ts +100 -0
  33. package/dist/services/feature-flag-service.js +1 -0
  34. package/dist/services/index.d.ts +1 -0
  35. package/dist/services/meta-service.d.ts +16 -0
  36. package/dist/services/meta-service.js +19 -0
  37. package/dist/services/webhook-service.d.ts +7 -2
  38. package/dist/services/webhook-service.js +11 -6
  39. package/dist/testing/service-tests/agent-run-service-tests.d.ts +2 -2
  40. package/dist/testing/service-tests/agent-storage-service-tests.d.ts +1 -1
  41. package/dist/testing/service-tests/channel-store-tests.d.ts +1 -1
  42. package/dist/testing/service-tests/credential-service-tests.d.ts +1 -1
  43. package/dist/testing/service-tests/deployment-service-tests.d.ts +1 -1
  44. package/dist/testing/service-tests/event-hub-store-tests.d.ts +1 -1
  45. package/dist/testing/service-tests/secret-service-tests.d.ts +1 -1
  46. package/dist/testing/service-tests/session-store-tests.d.ts +1 -1
  47. package/dist/testing/service-tests/workflow-run-service-tests.d.ts +1 -1
  48. package/dist/testing/service-tests/workflow-service-tests.d.ts +1 -1
  49. package/dist/types/core.types.d.ts +23 -0
  50. package/dist/wirings/agent/agent-rpc.d.ts +1 -1
  51. package/dist/wirings/agent/agent-turn.d.ts +1 -1
  52. package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +1 -1
  53. package/dist/wirings/channel/channel-common.d.ts +1 -1
  54. package/dist/wirings/channel/channel-rpc-validators.d.ts +2 -2
  55. package/dist/wirings/channel/channel-runner.d.ts +1 -1
  56. package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
  57. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
  58. package/dist/wirings/cli/channel/cli-approval.d.ts +2 -2
  59. package/dist/wirings/flag/assert-feature-available.d.ts +15 -0
  60. package/dist/wirings/flag/assert-feature-available.js +23 -0
  61. package/dist/wirings/flag/cached-flag-source.d.ts +73 -0
  62. package/dist/wirings/flag/cached-flag-source.js +96 -0
  63. package/dist/wirings/flag/define-feature-flags.d.ts +33 -0
  64. package/dist/wirings/flag/define-feature-flags.js +32 -0
  65. package/dist/wirings/flag/flag.types.d.ts +97 -0
  66. package/dist/wirings/flag/flag.types.js +1 -0
  67. package/dist/wirings/flag/index.d.ts +7 -0
  68. package/dist/wirings/flag/index.js +5 -0
  69. package/dist/wirings/flag/resolve-flag.d.ts +52 -0
  70. package/dist/wirings/flag/resolve-flag.js +90 -0
  71. package/dist/wirings/flag/validate-flag-definitions.d.ts +26 -0
  72. package/dist/wirings/flag/validate-flag-definitions.js +103 -0
  73. package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +8 -8
  74. package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +1 -1
  75. package/dist/wirings/workflow/workflow-queue-routing.d.ts +1 -1
  76. package/package.json +11 -5
  77. package/run-tests.sh +17 -9
  78. package/src/public-surface.json +26 -0
  79. package/src/agent-naming.test.ts +0 -68
  80. package/src/api-report.test.ts +0 -138
  81. package/src/app-alias-surface.test.ts +0 -179
  82. package/src/app-leaf-surface.test.ts +0 -222
  83. package/src/bootstrap-compat/root.ts +0 -20
  84. package/src/classification/column-form.test.ts +0 -97
  85. package/src/classification/column-form.ts +0 -55
  86. package/src/classification/data-classification.ts +0 -73
  87. package/src/classification/index.ts +0 -40
  88. package/src/classification/key-ids.ts +0 -2
  89. package/src/classification/secret-value.test.ts +0 -204
  90. package/src/classification/secret-value.ts +0 -106
  91. package/src/crypto-utils.test.ts +0 -668
  92. package/src/crypto-utils.ts +0 -460
  93. package/src/dev/hot-reload.test.ts +0 -587
  94. package/src/dev/hot-reload.ts +0 -225
  95. package/src/dev/module-runner.test.ts +0 -235
  96. package/src/dev/module-runner.ts +0 -138
  97. package/src/dev/reload-meta.test.ts +0 -183
  98. package/src/dev/reload-meta.ts +0 -144
  99. package/src/ecosystem-tier-removed.test.ts +0 -72
  100. package/src/env.ts +0 -1
  101. package/src/errors/error-handler.ts +0 -77
  102. package/src/errors/error.test.ts +0 -229
  103. package/src/errors/errors.ts +0 -393
  104. package/src/errors/index.ts +0 -11
  105. package/src/errors/serialized-error.ts +0 -12
  106. package/src/factory-functions.test.ts +0 -111
  107. package/src/function/abort-scope.test.ts +0 -97
  108. package/src/function/abort-scope.ts +0 -80
  109. package/src/function/function-meta.types.ts +0 -151
  110. package/src/function/function-runner.test.ts +0 -1619
  111. package/src/function/function-runner.ts +0 -499
  112. package/src/function/functions.types.ts +0 -319
  113. package/src/function/index.ts +0 -40
  114. package/src/function/list.types.test.ts +0 -100
  115. package/src/function/list.types.ts +0 -69
  116. package/src/function/pikku-request.test.ts +0 -35
  117. package/src/function/pikku-request.ts +0 -17
  118. package/src/gopass-secrets-removed.test.ts +0 -51
  119. package/src/handle-error.test.ts +0 -532
  120. package/src/handle-error.ts +0 -64
  121. package/src/middleware/auth-apikey.test.ts +0 -362
  122. package/src/middleware/auth-apikey.ts +0 -39
  123. package/src/middleware/auth-bearer.test.ts +0 -566
  124. package/src/middleware/auth-bearer.ts +0 -83
  125. package/src/middleware/auth-cookie.test.ts +0 -572
  126. package/src/middleware/auth-cookie.ts +0 -107
  127. package/src/middleware/cors.test.ts +0 -579
  128. package/src/middleware/cors.ts +0 -103
  129. package/src/middleware/index.ts +0 -30
  130. package/src/middleware/middleware-factories.ts +0 -76
  131. package/src/middleware/middleware.types.ts +0 -61
  132. package/src/middleware/remote-auth.test.ts +0 -547
  133. package/src/middleware/remote-auth.ts +0 -95
  134. package/src/middleware/remote-jobs-secret.ts +0 -35
  135. package/src/middleware/require-origin.test.ts +0 -115
  136. package/src/middleware/require-origin.ts +0 -79
  137. package/src/middleware/telemetry.ts +0 -83
  138. package/src/middleware-runner.test.ts +0 -578
  139. package/src/middleware-runner.ts +0 -232
  140. package/src/no-any-casts.test.ts +0 -57
  141. package/src/no-root-barrel.test.ts +0 -122
  142. package/src/permissions.test.ts +0 -256
  143. package/src/permissions.ts +0 -217
  144. package/src/pikku-state.test.ts +0 -198
  145. package/src/pikku-state.ts +0 -206
  146. package/src/production-barrels-stay-lean.test.ts +0 -110
  147. package/src/public-surface.test.ts +0 -133
  148. package/src/remote.test.ts +0 -173
  149. package/src/remote.ts +0 -56
  150. package/src/removed-legacy-exports.test.ts +0 -66
  151. package/src/run-tests-script.test.ts +0 -67
  152. package/src/schema.test.ts +0 -430
  153. package/src/schema.ts +0 -204
  154. package/src/scopes.test.ts +0 -203
  155. package/src/scopes.ts +0 -67
  156. package/src/services/agent-run-state-service.ts +0 -37
  157. package/src/services/agent-runner-service.ts +0 -238
  158. package/src/services/agent-storage-service.ts +0 -39
  159. package/src/services/ai-embedding-service.ts +0 -9
  160. package/src/services/audit-service.test.ts +0 -44
  161. package/src/services/audit-service.ts +0 -280
  162. package/src/services/content-service.ts +0 -65
  163. package/src/services/credential-service.ts +0 -20
  164. package/src/services/credential-wire-service.test.ts +0 -235
  165. package/src/services/credential-wire-service.ts +0 -120
  166. package/src/services/deployment-service.ts +0 -32
  167. package/src/services/email-service.test.ts +0 -100
  168. package/src/services/email-service.ts +0 -60
  169. package/src/services/email-template.test.ts +0 -311
  170. package/src/services/email-template.ts +0 -254
  171. package/src/services/file-scenario-run-store.test.ts +0 -349
  172. package/src/services/file-scenario-run-store.ts +0 -282
  173. package/src/services/gateway-service.ts +0 -5
  174. package/src/services/http-personas-converse.test.ts +0 -274
  175. package/src/services/http-personas.test.ts +0 -379
  176. package/src/services/http-personas.ts +0 -508
  177. package/src/services/in-memory-agent-run-state-service.ts +0 -87
  178. package/src/services/in-memory-queue-service.test.ts +0 -162
  179. package/src/services/in-memory-queue-service.ts +0 -78
  180. package/src/services/in-memory-session-store.test.ts +0 -58
  181. package/src/services/in-memory-session-store.ts +0 -20
  182. package/src/services/in-memory-trigger-service.ts +0 -47
  183. package/src/services/in-memory-workflow-service.test.ts +0 -430
  184. package/src/services/in-memory-workflow-service.ts +0 -595
  185. package/src/services/index.ts +0 -192
  186. package/src/services/istanbul-coverage-service.test.ts +0 -66
  187. package/src/services/istanbul-coverage-service.ts +0 -59
  188. package/src/services/jwt-service.ts +0 -15
  189. package/src/services/local-content-request-handler.test.ts +0 -240
  190. package/src/services/local-content-request-handler.ts +0 -295
  191. package/src/services/local-content.test.ts +0 -186
  192. package/src/services/local-content.ts +0 -242
  193. package/src/services/local-credential-service.ts +0 -63
  194. package/src/services/local-email-service.test.ts +0 -182
  195. package/src/services/local-email-service.ts +0 -43
  196. package/src/services/local-gateway-service.ts +0 -51
  197. package/src/services/local-secrets.test.ts +0 -95
  198. package/src/services/local-secrets.ts +0 -71
  199. package/src/services/local-variables.test.ts +0 -61
  200. package/src/services/local-variables.ts +0 -45
  201. package/src/services/logger-console.test.ts +0 -117
  202. package/src/services/logger-console.ts +0 -174
  203. package/src/services/logger.ts +0 -48
  204. package/src/services/meta-service.test.ts +0 -75
  205. package/src/services/meta-service.ts +0 -767
  206. package/src/services/persona-actor-secret.test.ts +0 -68
  207. package/src/services/persona-actor-secret.ts +0 -70
  208. package/src/services/persona-sign-in.test.ts +0 -219
  209. package/src/services/persona-sign-in.ts +0 -238
  210. package/src/services/personas-service.ts +0 -191
  211. package/src/services/pikku-user-id.test.ts +0 -62
  212. package/src/services/pikku-user-id.ts +0 -13
  213. package/src/services/queue-webhook-service.test.ts +0 -409
  214. package/src/services/queue-webhook-service.ts +0 -150
  215. package/src/services/remote-jobs.test.ts +0 -106
  216. package/src/services/remote-jobs.ts +0 -92
  217. package/src/services/scheduler-service.ts +0 -37
  218. package/src/services/schema-service.ts +0 -10
  219. package/src/services/scope-service.ts +0 -91
  220. package/src/services/scoped-credential-service.test.ts +0 -86
  221. package/src/services/scoped-credential-service.ts +0 -63
  222. package/src/services/scoped-secret-service.test.ts +0 -93
  223. package/src/services/scoped-secret-service.ts +0 -40
  224. package/src/services/secret-host-binding.test.ts +0 -138
  225. package/src/services/secret-host-binding.ts +0 -51
  226. package/src/services/secret-service.ts +0 -25
  227. package/src/services/secretless.test.ts +0 -54
  228. package/src/services/secretless.ts +0 -29
  229. package/src/services/session-store.ts +0 -9
  230. package/src/services/stub-tracker.test.ts +0 -104
  231. package/src/services/stub-tracker.ts +0 -175
  232. package/src/services/system-role-guard.test.ts +0 -96
  233. package/src/services/system-role-guard.ts +0 -71
  234. package/src/services/temporary-file-service.ts +0 -76
  235. package/src/services/trigger-service.ts +0 -5
  236. package/src/services/typed-credential-service.ts +0 -83
  237. package/src/services/typed-secret-service.test.ts +0 -204
  238. package/src/services/typed-secret-service.ts +0 -132
  239. package/src/services/typed-variables-service.test.ts +0 -166
  240. package/src/services/typed-variables-service.ts +0 -166
  241. package/src/services/user-session-service.test.ts +0 -147
  242. package/src/services/user-session-service.ts +0 -85
  243. package/src/services/v8-coverage-service.test.ts +0 -69
  244. package/src/services/v8-coverage-service.ts +0 -163
  245. package/src/services/variables-service.ts +0 -13
  246. package/src/services/webhook-service.ts +0 -147
  247. package/src/services/workflow-service.ts +0 -120
  248. package/src/side-effects-are-declared.test.ts +0 -84
  249. package/src/source-files-stay-composable.test.ts +0 -41
  250. package/src/template-alias-surface.test.ts +0 -240
  251. package/src/test-utils.ts +0 -38
  252. package/src/testing/index.ts +0 -3
  253. package/src/testing/service-tests/agent-run-service-tests.ts +0 -98
  254. package/src/testing/service-tests/agent-storage-service-tests.ts +0 -379
  255. package/src/testing/service-tests/channel-store-tests.ts +0 -98
  256. package/src/testing/service-tests/credential-service-tests.ts +0 -143
  257. package/src/testing/service-tests/deployment-service-tests.ts +0 -33
  258. package/src/testing/service-tests/event-hub-store-tests.ts +0 -48
  259. package/src/testing/service-tests/secret-service-tests.ts +0 -105
  260. package/src/testing/service-tests/session-store-tests.ts +0 -62
  261. package/src/testing/service-tests/workflow-run-service-tests.ts +0 -59
  262. package/src/testing/service-tests/workflow-service-tests.ts +0 -308
  263. package/src/testing/service-tests.ts +0 -95
  264. package/src/time-utils.test.ts +0 -56
  265. package/src/time-utils.ts +0 -89
  266. package/src/types/core.types.ts +0 -446
  267. package/src/types/index.ts +0 -25
  268. package/src/types/state.types.ts +0 -226
  269. package/src/types/typed-credentials.test.ts +0 -72
  270. package/src/utils/hash.test.ts +0 -68
  271. package/src/utils/hash.ts +0 -26
  272. package/src/utils/hmac.ts +0 -21
  273. package/src/utils/node-host-resolver.ts +0 -20
  274. package/src/utils/safe-fetch.test.ts +0 -515
  275. package/src/utils/safe-fetch.ts +0 -347
  276. package/src/utils.test.ts +0 -359
  277. package/src/utils.ts +0 -165
  278. package/src/version.test.ts +0 -80
  279. package/src/version.ts +0 -25
  280. package/src/wirings/actor-flow/actor-flow.types.ts +0 -40
  281. package/src/wirings/actor-flow/index.ts +0 -10
  282. package/src/wirings/actor-flow/run-conversation.test.ts +0 -187
  283. package/src/wirings/actor-flow/run-conversation.ts +0 -280
  284. package/src/wirings/addon/addon-auth-tags.test.ts +0 -219
  285. package/src/wirings/addon/addon-runner.ts +0 -236
  286. package/src/wirings/addon/addon-scopes.test.ts +0 -225
  287. package/src/wirings/addon/addon-secrets.test.ts +0 -391
  288. package/src/wirings/addon/index.ts +0 -12
  289. package/src/wirings/addon/remote-addon-auth.ts +0 -65
  290. package/src/wirings/addon/wire-addon.test.ts +0 -102
  291. package/src/wirings/addon/wire-addon.ts +0 -202
  292. package/src/wirings/addon/wire-remote-addon.ts +0 -41
  293. package/src/wirings/agent/agent-agui.test.ts +0 -1213
  294. package/src/wirings/agent/agent-agui.ts +0 -405
  295. package/src/wirings/agent/agent-authorization.test.ts +0 -208
  296. package/src/wirings/agent/agent-finalize.test.ts +0 -187
  297. package/src/wirings/agent/agent-finalize.ts +0 -197
  298. package/src/wirings/agent/agent-helpers.test.ts +0 -215
  299. package/src/wirings/agent/agent-helpers.ts +0 -96
  300. package/src/wirings/agent/agent-interrupt.test.ts +0 -833
  301. package/src/wirings/agent/agent-interrupt.ts +0 -400
  302. package/src/wirings/agent/agent-memory.test.ts +0 -397
  303. package/src/wirings/agent/agent-memory.ts +0 -496
  304. package/src/wirings/agent/agent-middleware.types.test.ts +0 -41
  305. package/src/wirings/agent/agent-model-config.test.ts +0 -103
  306. package/src/wirings/agent/agent-model-config.ts +0 -59
  307. package/src/wirings/agent/agent-prepare.test.ts +0 -977
  308. package/src/wirings/agent/agent-prepare.ts +0 -1083
  309. package/src/wirings/agent/agent-registry.test.ts +0 -455
  310. package/src/wirings/agent/agent-registry.ts +0 -99
  311. package/src/wirings/agent/agent-resume-authorization.test.ts +0 -206
  312. package/src/wirings/agent/agent-rpc.ts +0 -116
  313. package/src/wirings/agent/agent-runner.test.ts +0 -1229
  314. package/src/wirings/agent/agent-runner.ts +0 -858
  315. package/src/wirings/agent/agent-stream-delegate.test.ts +0 -381
  316. package/src/wirings/agent/agent-stream-output-hooks.test.ts +0 -353
  317. package/src/wirings/agent/agent-stream.test.ts +0 -1800
  318. package/src/wirings/agent/agent-stream.ts +0 -1639
  319. package/src/wirings/agent/agent-thread-ownership.test.ts +0 -297
  320. package/src/wirings/agent/agent-turn.test.ts +0 -65
  321. package/src/wirings/agent/agent-turn.ts +0 -122
  322. package/src/wirings/agent/agent-utils.ts +0 -20
  323. package/src/wirings/agent/agent.types.ts +0 -676
  324. package/src/wirings/agent/index.ts +0 -58
  325. package/src/wirings/agent/voice-input.test.ts +0 -220
  326. package/src/wirings/agent/voice-input.ts +0 -180
  327. package/src/wirings/agent/voice-output.test.ts +0 -510
  328. package/src/wirings/agent/voice-output.ts +0 -311
  329. package/src/wirings/agent-scorer/agent-scorer-grade.test.ts +0 -106
  330. package/src/wirings/agent-scorer/agent-scorer-grade.ts +0 -55
  331. package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +0 -285
  332. package/src/wirings/agent-scorer/agent-scorer-judge.ts +0 -180
  333. package/src/wirings/agent-scorer/agent-scorer-live.test.ts +0 -174
  334. package/src/wirings/agent-scorer/agent-scorer-live.ts +0 -56
  335. package/src/wirings/agent-scorer/agent-scorer-registry.ts +0 -66
  336. package/src/wirings/agent-scorer/agent-scorer-sampling.test.ts +0 -34
  337. package/src/wirings/agent-scorer/agent-scorer-sampling.ts +0 -36
  338. package/src/wirings/agent-scorer/agent-scorer-snapshots.test.ts +0 -49
  339. package/src/wirings/agent-scorer/agent-scorer-snapshots.ts +0 -46
  340. package/src/wirings/agent-scorer/agent-scorer-worker.test.ts +0 -122
  341. package/src/wirings/agent-scorer/agent-scorer-worker.ts +0 -71
  342. package/src/wirings/agent-scorer/agent-scorer.ts +0 -102
  343. package/src/wirings/agent-scorer/agent-scorer.types.ts +0 -128
  344. package/src/wirings/agent-scorer/index.ts +0 -23
  345. package/src/wirings/channel/channel-common.ts +0 -102
  346. package/src/wirings/channel/channel-handler-shapes.test.ts +0 -72
  347. package/src/wirings/channel/channel-handler.test.ts +0 -322
  348. package/src/wirings/channel/channel-handler.ts +0 -259
  349. package/src/wirings/channel/channel-host-rpc.test.ts +0 -150
  350. package/src/wirings/channel/channel-host-rpc.ts +0 -69
  351. package/src/wirings/channel/channel-middleware-runner.test.ts +0 -188
  352. package/src/wirings/channel/channel-middleware-runner.ts +0 -126
  353. package/src/wirings/channel/channel-rpc-registry.ts +0 -116
  354. package/src/wirings/channel/channel-rpc-responder.ts +0 -117
  355. package/src/wirings/channel/channel-rpc-service.ts +0 -132
  356. package/src/wirings/channel/channel-rpc-validators.ts +0 -65
  357. package/src/wirings/channel/channel-rpc.test.ts +0 -841
  358. package/src/wirings/channel/channel-rpc.ts +0 -5
  359. package/src/wirings/channel/channel-rpc.types.ts +0 -160
  360. package/src/wirings/channel/channel-runner.ts +0 -164
  361. package/src/wirings/channel/channel-store.ts +0 -35
  362. package/src/wirings/channel/channel.types.ts +0 -193
  363. package/src/wirings/channel/define-channel-routes.ts +0 -5
  364. package/src/wirings/channel/eventhub-service.ts +0 -16
  365. package/src/wirings/channel/eventhub-store.ts +0 -13
  366. package/src/wirings/channel/index.ts +0 -40
  367. package/src/wirings/channel/local/index.ts +0 -3
  368. package/src/wirings/channel/local/local-channel-handler.ts +0 -98
  369. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -339
  370. package/src/wirings/channel/local/local-channel-runner.ts +0 -271
  371. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -77
  372. package/src/wirings/channel/local/local-eventhub-service.ts +0 -69
  373. package/src/wirings/channel/log-channels.ts +0 -16
  374. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -135
  375. package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -60
  376. package/src/wirings/channel/serverless/index.ts +0 -6
  377. package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -328
  378. package/src/wirings/cli/channel/cli-approval.test.ts +0 -177
  379. package/src/wirings/cli/channel/cli-approval.ts +0 -135
  380. package/src/wirings/cli/channel/cli-channel-runner.ts +0 -118
  381. package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +0 -192
  382. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +0 -148
  383. package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +0 -480
  384. package/src/wirings/cli/channel/cli-raw-client-runner.ts +0 -188
  385. package/src/wirings/cli/channel/index.ts +0 -6
  386. package/src/wirings/cli/cli-runner.test.ts +0 -969
  387. package/src/wirings/cli/cli-runner.ts +0 -538
  388. package/src/wirings/cli/cli.types.ts +0 -388
  389. package/src/wirings/cli/command-parser.test.ts +0 -1120
  390. package/src/wirings/cli/command-parser.ts +0 -713
  391. package/src/wirings/cli/define-cli-commands.ts +0 -13
  392. package/src/wirings/cli/format-cli-error.test.ts +0 -91
  393. package/src/wirings/cli/format-cli-error.ts +0 -96
  394. package/src/wirings/cli/index.ts +0 -19
  395. package/src/wirings/credential/credential.types.ts +0 -37
  396. package/src/wirings/credential/define-credential.ts +0 -49
  397. package/src/wirings/credential/index.ts +0 -7
  398. package/src/wirings/credential/validate-credential-definitions.ts +0 -63
  399. package/src/wirings/gateway/gateway-authorization.test.ts +0 -575
  400. package/src/wirings/gateway/gateway-channel-meta.test.ts +0 -44
  401. package/src/wirings/gateway/gateway-runner.test.ts +0 -581
  402. package/src/wirings/gateway/gateway-runner.ts +0 -411
  403. package/src/wirings/gateway/gateway.types.ts +0 -137
  404. package/src/wirings/gateway/index.ts +0 -15
  405. package/src/wirings/http/http-routes.test.ts +0 -318
  406. package/src/wirings/http/http-routes.ts +0 -111
  407. package/src/wirings/http/http-runner-addon-ref.test.ts +0 -238
  408. package/src/wirings/http/http-runner.test.ts +0 -503
  409. package/src/wirings/http/http-runner.ts +0 -462
  410. package/src/wirings/http/http.types.ts +0 -307
  411. package/src/wirings/http/index.ts +0 -27
  412. package/src/wirings/http/log-http-routes.ts +0 -18
  413. package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -318
  414. package/src/wirings/http/pikku-fetch-http-request.ts +0 -260
  415. package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -123
  416. package/src/wirings/http/pikku-fetch-http-response.ts +0 -149
  417. package/src/wirings/http/routers/http-router.ts +0 -13
  418. package/src/wirings/http/routers/path-to-regex.test.ts +0 -306
  419. package/src/wirings/http/routers/path-to-regex.ts +0 -115
  420. package/src/wirings/http/web-request.test.ts +0 -382
  421. package/src/wirings/http/web-request.ts +0 -162
  422. package/src/wirings/mcp/index.ts +0 -26
  423. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -388
  424. package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
  425. package/src/wirings/mcp/mcp-runner.test.ts +0 -588
  426. package/src/wirings/mcp/mcp-runner.ts +0 -330
  427. package/src/wirings/mcp/mcp.types.ts +0 -199
  428. package/src/wirings/node/index.ts +0 -2
  429. package/src/wirings/node/node.types.ts +0 -23
  430. package/src/wirings/oauth2/index.ts +0 -1
  431. package/src/wirings/oauth2/oauth2.types.ts +0 -12
  432. package/src/wirings/persona/define-personas.ts +0 -33
  433. package/src/wirings/persona/index.ts +0 -75
  434. package/src/wirings/persona/persona-app-scopes.test.ts +0 -47
  435. package/src/wirings/persona/persona-app-scopes.ts +0 -74
  436. package/src/wirings/persona/persona-email.ts +0 -87
  437. package/src/wirings/persona/persona-environments.test.ts +0 -194
  438. package/src/wirings/persona/persona-environments.ts +0 -138
  439. package/src/wirings/persona/persona-mailbox.ts +0 -156
  440. package/src/wirings/persona/persona.test.ts +0 -230
  441. package/src/wirings/persona/persona.types.ts +0 -156
  442. package/src/wirings/persona/validate-personas.ts +0 -137
  443. package/src/wirings/queue/index.ts +0 -29
  444. package/src/wirings/queue/queue-identity.test.ts +0 -454
  445. package/src/wirings/queue/queue-identity.ts +0 -176
  446. package/src/wirings/queue/queue-runner.test.ts +0 -705
  447. package/src/wirings/queue/queue-runner.ts +0 -181
  448. package/src/wirings/queue/queue.types.ts +0 -161
  449. package/src/wirings/queue/register-queue-helper.ts +0 -46
  450. package/src/wirings/queue/signed-queue-service.ts +0 -60
  451. package/src/wirings/queue/validate-worker-config.test.ts +0 -108
  452. package/src/wirings/queue/validate-worker-config.ts +0 -90
  453. package/src/wirings/role/define-system-role.ts +0 -33
  454. package/src/wirings/role/index.ts +0 -13
  455. package/src/wirings/role/role.test.ts +0 -104
  456. package/src/wirings/role/role.types.ts +0 -47
  457. package/src/wirings/role/validate-role-definitions.ts +0 -93
  458. package/src/wirings/rpc/index.ts +0 -8
  459. package/src/wirings/rpc/rpc-runner.test.ts +0 -1130
  460. package/src/wirings/rpc/rpc-runner.ts +0 -569
  461. package/src/wirings/rpc/rpc-types.ts +0 -87
  462. package/src/wirings/scheduler/index.ts +0 -11
  463. package/src/wirings/scheduler/log-schedulers.ts +0 -16
  464. package/src/wirings/scheduler/scheduler-runner.test.ts +0 -835
  465. package/src/wirings/scheduler/scheduler-runner.ts +0 -138
  466. package/src/wirings/scheduler/scheduler.types.ts +0 -42
  467. package/src/wirings/scope/define-scope.ts +0 -33
  468. package/src/wirings/scope/index.ts +0 -15
  469. package/src/wirings/scope/scope.test.ts +0 -159
  470. package/src/wirings/scope/scope.types.ts +0 -42
  471. package/src/wirings/scope/validate-scope-definitions.ts +0 -107
  472. package/src/wirings/secret/index.ts +0 -9
  473. package/src/wirings/secret/secret.types.ts +0 -70
  474. package/src/wirings/secret/validate-secret-definitions.test.ts +0 -232
  475. package/src/wirings/secret/validate-secret-definitions.ts +0 -88
  476. package/src/wirings/trigger/index.ts +0 -9
  477. package/src/wirings/trigger/pikku-trigger-service.ts +0 -107
  478. package/src/wirings/trigger/trigger-runner.test.ts +0 -78
  479. package/src/wirings/trigger/trigger-runner.ts +0 -113
  480. package/src/wirings/trigger/trigger.types.ts +0 -100
  481. package/src/wirings/variable/index.ts +0 -8
  482. package/src/wirings/variable/validate-variable-definitions.test.ts +0 -115
  483. package/src/wirings/variable/validate-variable-definitions.ts +0 -71
  484. package/src/wirings/variable/variable.types.ts +0 -40
  485. package/src/wirings/virtual-user/index.ts +0 -107
  486. package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +0 -115
  487. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +0 -95
  488. package/src/wirings/virtual-user/run-virtual-user.test.ts +0 -774
  489. package/src/wirings/virtual-user/run-virtual-user.ts +0 -684
  490. package/src/wirings/virtual-user/virtual-user-agents.test.ts +0 -72
  491. package/src/wirings/virtual-user/virtual-user-agents.ts +0 -62
  492. package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +0 -215
  493. package/src/wirings/virtual-user/virtual-user-catalogue.ts +0 -184
  494. package/src/wirings/virtual-user/virtual-user-derive.test.ts +0 -426
  495. package/src/wirings/virtual-user/virtual-user-derive.ts +0 -161
  496. package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +0 -68
  497. package/src/wirings/virtual-user/virtual-user-dispositions.ts +0 -210
  498. package/src/wirings/virtual-user/virtual-user-intents.test.ts +0 -218
  499. package/src/wirings/virtual-user/virtual-user-intents.ts +0 -185
  500. package/src/wirings/virtual-user/virtual-user-rng.test.ts +0 -72
  501. package/src/wirings/virtual-user/virtual-user-rng.ts +0 -50
  502. package/src/wirings/virtual-user/virtual-user-run-store.ts +0 -131
  503. package/src/wirings/virtual-user/virtual-user-scaffold.test.ts +0 -854
  504. package/src/wirings/virtual-user/virtual-user-scaffold.ts +0 -664
  505. package/src/wirings/virtual-user/virtual-user-schedule-store.ts +0 -93
  506. package/src/wirings/virtual-user/virtual-user-schedule.test.ts +0 -280
  507. package/src/wirings/virtual-user/virtual-user-schedule.ts +0 -156
  508. package/src/wirings/virtual-user/virtual-user-target.ts +0 -47
  509. package/src/wirings/virtual-user/virtual-user.types.ts +0 -215
  510. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -709
  511. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -25
  512. package/src/wirings/workflow/feature.test.ts +0 -131
  513. package/src/wirings/workflow/feature.ts +0 -59
  514. package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +0 -569
  515. package/src/wirings/workflow/graph/graph-foreach.test.ts +0 -626
  516. package/src/wirings/workflow/graph/graph-node.ts +0 -115
  517. package/src/wirings/workflow/graph/graph-runner.test.ts +0 -1049
  518. package/src/wirings/workflow/graph/graph-runner.ts +0 -1376
  519. package/src/wirings/workflow/graph/graph-validation.test.ts +0 -27
  520. package/src/wirings/workflow/graph/graph-validation.ts +0 -41
  521. package/src/wirings/workflow/graph/template.test.ts +0 -49
  522. package/src/wirings/workflow/graph/template.ts +0 -42
  523. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -39
  524. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -75
  525. package/src/wirings/workflow/index.ts +0 -107
  526. package/src/wirings/workflow/pikku-scenario-service.ts +0 -1013
  527. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -963
  528. package/src/wirings/workflow/pikku-workflow-service.ts +0 -1993
  529. package/src/wirings/workflow/run-timeline.test.ts +0 -199
  530. package/src/wirings/workflow/run-timeline.ts +0 -185
  531. package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -107
  532. package/src/wirings/workflow/scenario-cookie-jar.ts +0 -57
  533. package/src/wirings/workflow/scenario-expectations.test.ts +0 -238
  534. package/src/wirings/workflow/scenario-hooks.test.ts +0 -259
  535. package/src/wirings/workflow/scenario-poll.test.ts +0 -64
  536. package/src/wirings/workflow/scenario-poll.ts +0 -27
  537. package/src/wirings/workflow/scenario-prose.test.ts +0 -275
  538. package/src/wirings/workflow/scenario-prose.ts +0 -86
  539. package/src/wirings/workflow/scenario-run.types.ts +0 -193
  540. package/src/wirings/workflow/scenario-service.test.ts +0 -147
  541. package/src/wirings/workflow/scenario-step-guards.ts +0 -23
  542. package/src/wirings/workflow/scenario-step.test.ts +0 -800
  543. package/src/wirings/workflow/scenario-step.types.ts +0 -262
  544. package/src/wirings/workflow/scenario-surface.test.ts +0 -146
  545. package/src/wirings/workflow/scenario-surface.ts +0 -71
  546. package/src/wirings/workflow/scenario.types.ts +0 -63
  547. package/src/wirings/workflow/workflow-approval-audit.ts +0 -47
  548. package/src/wirings/workflow/workflow-approval-policy.test.ts +0 -594
  549. package/src/wirings/workflow/workflow-approval-policy.ts +0 -68
  550. package/src/wirings/workflow/workflow-approval.ts +0 -290
  551. package/src/wirings/workflow/workflow-child-run-session.test.ts +0 -168
  552. package/src/wirings/workflow/workflow-constants.ts +0 -66
  553. package/src/wirings/workflow/workflow-dispatch-durability.test.ts +0 -116
  554. package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -55
  555. package/src/wirings/workflow/workflow-dispatch-relay.test.ts +0 -128
  556. package/src/wirings/workflow/workflow-errors.ts +0 -132
  557. package/src/wirings/workflow/workflow-inline-authority.test.ts +0 -175
  558. package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -51
  559. package/src/wirings/workflow/workflow-invocation-id.ts +0 -28
  560. package/src/wirings/workflow/workflow-meta-resolver.ts +0 -45
  561. package/src/wirings/workflow/workflow-mirror.test.ts +0 -171
  562. package/src/wirings/workflow/workflow-missing-meta.test.ts +0 -92
  563. package/src/wirings/workflow/workflow-on-error.test.ts +0 -145
  564. package/src/wirings/workflow/workflow-queue-routing.ts +0 -129
  565. package/src/wirings/workflow/workflow-queue-wiring.ts +0 -149
  566. package/src/wirings/workflow/workflow-queue-workers.test.ts +0 -131
  567. package/src/wirings/workflow/workflow-queue-workers.ts +0 -66
  568. package/src/wirings/workflow/workflow-recovery.ts +0 -192
  569. package/src/wirings/workflow/workflow-replay-snapshot.test.ts +0 -140
  570. package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -113
  571. package/src/wirings/workflow/workflow-run-authority.test.ts +0 -212
  572. package/src/wirings/workflow/workflow-run-context.test.ts +0 -172
  573. package/src/wirings/workflow/workflow-run-engine.types.ts +0 -92
  574. package/src/wirings/workflow/workflow-run-ownership.ts +0 -37
  575. package/src/wirings/workflow/workflow-run-polling.test.ts +0 -127
  576. package/src/wirings/workflow/workflow-stalled-recovery.test.ts +0 -152
  577. package/src/wirings/workflow/workflow-status-stream.test.ts +0 -354
  578. package/src/wirings/workflow/workflow-status-stream.ts +0 -144
  579. package/src/wirings/workflow/workflow-step-claim.ts +0 -46
  580. package/src/wirings/workflow/workflow-step-ordinal.test.ts +0 -94
  581. package/src/wirings/workflow/workflow-step-session.test.ts +0 -87
  582. package/src/wirings/workflow/workflow-suspend.ts +0 -61
  583. package/src/wirings/workflow/workflow-terminal-run-guard.test.ts +0 -105
  584. package/src/wirings/workflow/workflow.types.ts +0 -268
  585. package/src/wirings-stay-decoupled.test.ts +0 -130
  586. package/tsconfig.json +0 -14
  587. package/tsconfig.tsbuildinfo +0 -1
  588. package/tsconfig.type-tests.json +0 -15
@@ -1,1120 +0,0 @@
1
- import { test, describe, beforeEach, after } from 'node:test'
2
- import * as assert from 'assert'
3
- import { parseCLIArguments, generateCommandHelp } from './command-parser.js'
4
- import type { CLIMeta } from './cli.types.js'
5
- import { pikkuState, resetPikkuState } from '../../pikku-state.js'
6
-
7
- const testMeta: CLIMeta = {
8
- programs: {
9
- 'test-cli': {
10
- program: 'test-cli',
11
- options: {
12
- verbose: {
13
- description: 'Enable verbose output',
14
- short: 'v',
15
- default: false,
16
- },
17
- },
18
- commands: {
19
- greet: {
20
- parameters: '<name>',
21
- pikkuFuncId: 'greetFunc',
22
- positionals: [{ name: 'name', required: true }],
23
- options: {
24
- loud: {
25
- description: 'Use loud greeting',
26
- short: 'l',
27
- default: false,
28
- },
29
- },
30
- },
31
- user: {
32
- pikkuFuncId: '',
33
- positionals: [],
34
- options: {},
35
- subcommands: {
36
- create: {
37
- parameters: '<name> <email>',
38
- pikkuFuncId: 'createUserFunc',
39
- positionals: [
40
- { name: 'name', required: true },
41
- { name: 'email', required: true },
42
- ],
43
- options: {
44
- role: {
45
- description: 'User role',
46
- short: 'r',
47
- default: 'user',
48
- choices: ['admin', 'user', 'guest'],
49
- },
50
- },
51
- },
52
- delete: {
53
- parameters: '<id>',
54
- pikkuFuncId: 'deleteUserFunc',
55
- positionals: [{ name: 'id', required: true }],
56
- options: {
57
- force: {
58
- description: 'Force delete',
59
- short: 'f',
60
- default: false,
61
- },
62
- },
63
- },
64
- },
65
- },
66
- files: {
67
- parameters: '<paths...>',
68
- pikkuFuncId: 'filesFunc',
69
- positionals: [{ name: 'paths', required: true, variadic: true }],
70
- options: {},
71
- },
72
- optional: {
73
- parameters: '[name]',
74
- pikkuFuncId: 'optionalFunc',
75
- positionals: [{ name: 'name', required: false }],
76
- options: {},
77
- },
78
- serve: {
79
- pikkuFuncId: 'serveFunc',
80
- positionals: [],
81
- options: {
82
- browser: {
83
- description: 'Open a browser',
84
- default: true,
85
- },
86
- port: {
87
- description: 'Port to listen on',
88
- default: 8080,
89
- },
90
- },
91
- },
92
- deploy: {
93
- pikkuFuncId: 'deployFunc',
94
- positionals: [],
95
- options: {
96
- token: {
97
- description: 'Auth token',
98
- short: 'k',
99
- type: 'string',
100
- },
101
- tags: {
102
- description: 'Tags to include',
103
- short: 't',
104
- type: 'string[]',
105
- },
106
- note: {
107
- description: 'Free-form note',
108
- },
109
- dryRun: {
110
- description: 'Report without deploying',
111
- type: 'boolean',
112
- short: 'D',
113
- },
114
- },
115
- },
116
- },
117
- },
118
- },
119
- renderers: {},
120
- }
121
-
122
- describe('Command Parser', () => {
123
- describe('parseCLIArguments', () => {
124
- test('should parse simple command with required positional', () => {
125
- const result = parseCLIArguments(['greet', 'Alice'], 'test-cli', testMeta)
126
-
127
- assert.strictEqual(result.program, 'test-cli')
128
- assert.deepStrictEqual(result.commandPath, ['greet'])
129
- assert.deepStrictEqual(result.positionals, { name: 'Alice' })
130
- assert.strictEqual(result.errors.length, 0)
131
- })
132
-
133
- test('should parse command with boolean flag', () => {
134
- const result = parseCLIArguments(
135
- ['greet', 'Alice', '--loud'],
136
- 'test-cli',
137
- testMeta
138
- )
139
-
140
- assert.deepStrictEqual(result.positionals, { name: 'Alice' })
141
- assert.deepStrictEqual(result.options, { loud: true, verbose: false })
142
- assert.strictEqual(result.errors.length, 0)
143
- })
144
-
145
- test('should turn a boolean option off with --no-<flag>', () => {
146
- const result = parseCLIArguments(
147
- ['serve', '--no-browser'],
148
- 'test-cli',
149
- testMeta
150
- )
151
-
152
- assert.strictEqual(result.options.browser, false)
153
- assert.strictEqual(result.errors.length, 0)
154
- assert.deepStrictEqual(
155
- result.warnings ?? [],
156
- [],
157
- '--no-browser is the negation of a known option, not an unknown one'
158
- )
159
- })
160
-
161
- test('should leave a boolean option at its default when not negated', () => {
162
- const result = parseCLIArguments(['serve'], 'test-cli', testMeta)
163
-
164
- assert.strictEqual(result.options.browser, true)
165
- })
166
-
167
- test('should not consume the next argument when negating', () => {
168
- const result = parseCLIArguments(
169
- ['serve', '--no-browser', '--port', '4077'],
170
- 'test-cli',
171
- testMeta
172
- )
173
-
174
- assert.strictEqual(result.options.browser, false)
175
- assert.strictEqual(result.options.port, 4077)
176
- })
177
-
178
- test('should still warn about an unknown --no-<flag>', () => {
179
- const result = parseCLIArguments(
180
- ['serve', '--no-telemetry'],
181
- 'test-cli',
182
- testMeta
183
- )
184
-
185
- assert.ok(
186
- (result.warnings ?? []).length > 0,
187
- 'negating an option that does not exist is a typo, not a feature'
188
- )
189
- })
190
-
191
- test('should parse command with short flag', () => {
192
- const result = parseCLIArguments(
193
- ['greet', 'Alice', '-l'],
194
- 'test-cli',
195
- testMeta
196
- )
197
-
198
- assert.deepStrictEqual(result.options, { loud: true, verbose: false })
199
- assert.strictEqual(result.errors.length, 0)
200
- })
201
-
202
- test('should parse command with option value using space', () => {
203
- const result = parseCLIArguments(
204
- ['user', 'create', 'Bob', 'bob@example.com', '--role', 'admin'],
205
- 'test-cli',
206
- testMeta
207
- )
208
-
209
- assert.deepStrictEqual(result.commandPath, ['user', 'create'])
210
- assert.deepStrictEqual(result.positionals, {
211
- name: 'Bob',
212
- email: 'bob@example.com',
213
- })
214
- assert.deepStrictEqual(result.options, { role: 'admin', verbose: false })
215
- assert.strictEqual(result.errors.length, 0)
216
- })
217
-
218
- test('should parse command with option value using equals', () => {
219
- const result = parseCLIArguments(
220
- ['user', 'create', 'Bob', 'bob@example.com', '--role=admin'],
221
- 'test-cli',
222
- testMeta
223
- )
224
-
225
- assert.deepStrictEqual(result.options, { role: 'admin', verbose: false })
226
- assert.strictEqual(result.errors.length, 0)
227
- })
228
-
229
- test('should parse command with short option and value', () => {
230
- const result = parseCLIArguments(
231
- ['user', 'create', 'Bob', 'bob@example.com', '-r', 'admin'],
232
- 'test-cli',
233
- testMeta
234
- )
235
-
236
- assert.deepStrictEqual(result.options, { role: 'admin', verbose: false })
237
- assert.strictEqual(result.errors.length, 0)
238
- })
239
-
240
- test('should apply default option values', () => {
241
- const result = parseCLIArguments(['greet', 'Alice'], 'test-cli', testMeta)
242
-
243
- assert.deepStrictEqual(result.options, { loud: false, verbose: false })
244
- })
245
-
246
- test('should parse subcommands', () => {
247
- const result = parseCLIArguments(
248
- ['user', 'create', 'Alice', 'alice@example.com'],
249
- 'test-cli',
250
- testMeta
251
- )
252
-
253
- assert.deepStrictEqual(result.commandPath, ['user', 'create'])
254
- assert.deepStrictEqual(result.positionals, {
255
- name: 'Alice',
256
- email: 'alice@example.com',
257
- })
258
- })
259
-
260
- test('should report missing subcommand for a group node with no func', () => {
261
- const result = parseCLIArguments(['user'], 'test-cli', testMeta)
262
-
263
- assert.deepStrictEqual(result.commandPath, ['user'])
264
- assert.ok(
265
- result.errors.some((error) => error.startsWith('Missing subcommand:')),
266
- `expected a "Missing subcommand:" error, got: ${JSON.stringify(result.errors)}`
267
- )
268
- })
269
-
270
- test('should not flag a runnable command as a missing subcommand', () => {
271
- const result = parseCLIArguments(['greet', 'Alice'], 'test-cli', testMeta)
272
-
273
- assert.deepStrictEqual(result.commandPath, ['greet'])
274
- assert.strictEqual(result.errors.length, 0)
275
- })
276
-
277
- test('should parse variadic positionals', () => {
278
- const result = parseCLIArguments(
279
- ['files', 'file1.txt', 'file2.txt', 'file3.txt'],
280
- 'test-cli',
281
- testMeta
282
- )
283
-
284
- assert.deepStrictEqual(result.positionals, {
285
- paths: ['file1.txt', 'file2.txt', 'file3.txt'],
286
- })
287
- assert.strictEqual(result.errors.length, 0)
288
- })
289
-
290
- test('should parse optional positionals when provided', () => {
291
- const result = parseCLIArguments(
292
- ['optional', 'Alice'],
293
- 'test-cli',
294
- testMeta
295
- )
296
-
297
- assert.deepStrictEqual(result.positionals, { name: 'Alice' })
298
- assert.strictEqual(result.errors.length, 0)
299
- })
300
-
301
- test('should handle missing optional positionals', () => {
302
- const result = parseCLIArguments(['optional'], 'test-cli', testMeta)
303
-
304
- assert.deepStrictEqual(result.positionals, {})
305
- assert.strictEqual(result.errors.length, 0)
306
- })
307
-
308
- test('should handle global options', () => {
309
- const result = parseCLIArguments(
310
- ['greet', 'Alice', '--verbose'],
311
- 'test-cli',
312
- testMeta
313
- )
314
-
315
- assert.deepStrictEqual(result.options, { loud: false, verbose: true })
316
- assert.strictEqual(result.errors.length, 0)
317
- })
318
-
319
- test('should combine multiple short flags', () => {
320
- const result = parseCLIArguments(
321
- ['greet', 'Alice', '-lv'],
322
- 'test-cli',
323
- testMeta
324
- )
325
-
326
- assert.deepStrictEqual(result.options, { loud: true, verbose: true })
327
- assert.strictEqual(result.errors.length, 0)
328
- })
329
-
330
- test('should report error for missing required positional', () => {
331
- const result = parseCLIArguments(['greet'], 'test-cli', testMeta)
332
-
333
- assert.ok(result.errors.length > 0)
334
- assert.ok(result.errors[0].includes('Missing required argument: name'))
335
- })
336
-
337
- test('should report error for invalid choice', () => {
338
- const result = parseCLIArguments(
339
- ['user', 'create', 'Bob', 'bob@example.com', '--role', 'invalid'],
340
- 'test-cli',
341
- testMeta
342
- )
343
-
344
- assert.ok(result.errors.length > 0)
345
- assert.ok(result.errors[0].includes('Invalid value'))
346
- })
347
-
348
- test('should report error for unknown option', () => {
349
- const result = parseCLIArguments(
350
- ['greet', 'Alice', '--unknown'],
351
- 'test-cli',
352
- testMeta
353
- )
354
-
355
- assert.strictEqual(result.options.unknown, true)
356
- assert.strictEqual(result.errors.length, 0)
357
- })
358
-
359
- test('should report error for unknown short flag', () => {
360
- const result = parseCLIArguments(
361
- ['greet', 'Alice', '-x'],
362
- 'test-cli',
363
- testMeta
364
- )
365
-
366
- assert.ok(result.errors.length > 0)
367
- assert.ok(result.errors[0].includes('Unknown option: -x'))
368
- })
369
-
370
- test('should report error for extra positional arguments', () => {
371
- const result = parseCLIArguments(
372
- ['greet', 'Alice', 'Bob'],
373
- 'test-cli',
374
- testMeta
375
- )
376
-
377
- assert.ok(result.errors.length > 0)
378
- assert.ok(result.errors[0].includes('Unexpected arguments'))
379
- })
380
-
381
- test('should report error for unknown command', () => {
382
- const result = parseCLIArguments(['unknown'], 'test-cli', testMeta)
383
-
384
- assert.ok(result.errors.length > 0)
385
- assert.ok(result.errors[0].includes('Unknown command'))
386
- })
387
-
388
- test('should report error for nonexistent program', () => {
389
- const result = parseCLIArguments(['test'], 'nonexistent', testMeta)
390
-
391
- assert.ok(result.errors.length > 0)
392
- assert.ok(result.errors[0].includes('Program not found'))
393
- })
394
-
395
- test('should parse number values correctly', () => {
396
- const metaWithNumber: CLIMeta = {
397
- programs: {
398
- 'num-cli': {
399
- program: 'num-cli',
400
- options: {},
401
- commands: {
402
- test: {
403
- pikkuFuncId: 'testFunc',
404
- positionals: [],
405
- options: {
406
- port: {
407
- description: 'Port number',
408
- default: 3000,
409
- },
410
- },
411
- },
412
- },
413
- },
414
- },
415
- renderers: {},
416
- }
417
-
418
- const result = parseCLIArguments(
419
- ['test', '--port', '8080'],
420
- 'num-cli',
421
- metaWithNumber
422
- )
423
-
424
- assert.strictEqual(result.options.port, 8080)
425
- assert.strictEqual(typeof result.options.port, 'number')
426
- })
427
-
428
- test('should parse boolean values correctly', () => {
429
- const result = parseCLIArguments(
430
- ['greet', 'Alice', '--loud', 'true'],
431
- 'test-cli',
432
- testMeta
433
- )
434
-
435
- assert.strictEqual(result.options.loud, true)
436
- })
437
-
438
- test('should handle empty variadic positionals when required', () => {
439
- const result = parseCLIArguments(['files'], 'test-cli', testMeta)
440
-
441
- assert.ok(result.errors.length > 0)
442
- assert.ok(result.errors[0].includes('Missing required argument: paths'))
443
- })
444
- })
445
-
446
- describe('generateCommandHelp', () => {
447
- test('should generate help for program root', () => {
448
- const help = generateCommandHelp('test-cli', testMeta)
449
-
450
- assert.ok(help.includes('Usage: test-cli <command>'))
451
- assert.ok(help.includes('Commands:'))
452
- assert.ok(help.includes('greet'))
453
- assert.ok(help.includes('Options:'))
454
- assert.ok(help.includes('--verbose'))
455
- })
456
-
457
- test('should generate help for specific command', () => {
458
- const help = generateCommandHelp('test-cli', testMeta, ['greet'])
459
-
460
- assert.ok(help.includes('Usage: test-cli greet'))
461
- assert.ok(help.includes('<name>'))
462
- assert.ok(help.includes('--loud'))
463
- assert.ok(help.includes('Use loud greeting'))
464
- })
465
-
466
- test('should generate help for subcommand', () => {
467
- const help = generateCommandHelp('test-cli', testMeta, ['user', 'create'])
468
-
469
- assert.ok(help.includes('Usage: test-cli user create'))
470
- assert.ok(help.includes('<name>'))
471
- assert.ok(help.includes('<email>'))
472
- assert.ok(help.includes('--role'))
473
- })
474
-
475
- test('should show command description if available', () => {
476
- const metaWithDesc: CLIMeta = {
477
- programs: {
478
- 'test-cli': {
479
- program: 'test-cli',
480
- options: {},
481
- commands: {
482
- greet: {
483
- parameters: '<name>',
484
- pikkuFuncId: 'greetFunc',
485
- description: 'Greet a user',
486
- positionals: [{ name: 'name', required: true }],
487
- options: {},
488
- },
489
- },
490
- },
491
- },
492
- renderers: {},
493
- }
494
-
495
- const help = generateCommandHelp('test-cli', metaWithDesc, ['greet'])
496
-
497
- assert.ok(help.includes('Greet a user'))
498
- })
499
-
500
- test('should show option defaults in help', () => {
501
- const help = generateCommandHelp('test-cli', testMeta, ['greet'])
502
-
503
- assert.ok(help.includes('(default: false)'))
504
- })
505
-
506
- test('should show option choices in help', () => {
507
- const help = generateCommandHelp('test-cli', testMeta, ['user', 'create'])
508
-
509
- assert.ok(help.includes('[choices: admin, user, guest]'))
510
- })
511
-
512
- test('should show subcommands in help', () => {
513
- const help = generateCommandHelp('test-cli', testMeta, ['user'])
514
-
515
- assert.ok(help.includes('Subcommands:'))
516
- assert.ok(help.includes('create'))
517
- assert.ok(help.includes('delete'))
518
- })
519
-
520
- test('should show variadic positionals in help', () => {
521
- const help = generateCommandHelp('test-cli', testMeta, ['files'])
522
-
523
- assert.ok(help.includes('paths...'))
524
- assert.ok(help.includes('<required>'))
525
- })
526
-
527
- test('should show optional positionals in help', () => {
528
- const help = generateCommandHelp('test-cli', testMeta, ['optional'])
529
-
530
- assert.ok(help.includes('name'))
531
- assert.ok(help.includes('[optional]'))
532
- })
533
-
534
- test('should return error for nonexistent program', () => {
535
- const help = generateCommandHelp('nonexistent', testMeta)
536
-
537
- assert.ok(help.includes('Program not found'))
538
- })
539
-
540
- test('should return error for nonexistent command', () => {
541
- const help = generateCommandHelp('test-cli', testMeta, ['nonexistent'])
542
-
543
- assert.ok(help.includes('Unknown command'))
544
- })
545
- })
546
-
547
- describe('camelCase ↔ kebab-case options', () => {
548
- const kebabMeta: CLIMeta = {
549
- programs: {
550
- 'test-cli': {
551
- program: 'test-cli',
552
- options: {},
553
- commands: {
554
- deploy: {
555
- pikkuFuncId: 'deployFunc',
556
- positionals: [],
557
- options: {
558
- autoApply: {
559
- description: 'Deploy without the confirmation prompt',
560
- default: false,
561
- },
562
- apiUrl: { description: 'Override the API URL' },
563
- token: { description: 'Auth token', required: true },
564
- },
565
- },
566
- },
567
- },
568
- },
569
- renderers: {},
570
- }
571
-
572
- test('renders camelCase option keys as kebab-case in help', () => {
573
- const help = generateCommandHelp('test-cli', kebabMeta, ['deploy'])
574
-
575
- assert.ok(help.includes('--auto-apply'), 'expected --auto-apply')
576
- assert.ok(help.includes('--api-url'), 'expected --api-url')
577
- assert.ok(!help.includes('--autoApply'), 'should not show camelCase')
578
- assert.ok(!help.includes('--apiUrl'), 'should not show camelCase')
579
- })
580
-
581
- test('accepts the kebab-case form and maps it to the camelCase field', () => {
582
- const result = parseCLIArguments(
583
- ['deploy', '--auto-apply', '--api-url', 'https://x'],
584
- 'test-cli',
585
- kebabMeta
586
- )
587
-
588
- assert.strictEqual(result.options.autoApply, true)
589
- assert.strictEqual(result.options.apiUrl, 'https://x')
590
- })
591
-
592
- test('still accepts the camelCase form (back-compat)', () => {
593
- const result = parseCLIArguments(
594
- ['deploy', '--autoApply', '--apiUrl', 'https://x'],
595
- 'test-cli',
596
- kebabMeta
597
- )
598
-
599
- assert.strictEqual(result.options.autoApply, true)
600
- assert.strictEqual(result.options.apiUrl, 'https://x')
601
- })
602
-
603
- test('renders missing-required-option errors in kebab-case', () => {
604
- const result = parseCLIArguments(['deploy'], 'test-cli', kebabMeta)
605
-
606
- assert.ok(
607
- result.errors.some((e) => e.includes('--token')),
608
- 'expected a missing --token error'
609
- )
610
- })
611
- })
612
-
613
- describe('unknown long options', () => {
614
- const listMeta: CLIMeta = {
615
- programs: {
616
- 'test-cli': {
617
- program: 'test-cli',
618
- options: {},
619
- commands: {
620
- list: {
621
- pikkuFuncId: 'listFunc',
622
- positionals: [],
623
- options: {
624
- section: { description: 'Section to list', default: 'all' },
625
- autoApply: {
626
- description: 'Apply automatically',
627
- default: false,
628
- },
629
- },
630
- },
631
- },
632
- },
633
- },
634
- renderers: {},
635
- }
636
-
637
- test('warns (but does not error) on an unknown --opt value option', () => {
638
- const result = parseCLIArguments(
639
- ['list', '--sektion', 'functions'],
640
- 'test-cli',
641
- listMeta
642
- )
643
-
644
- assert.strictEqual(result.errors.length, 0, 'should stay non-fatal')
645
- assert.strictEqual(result.warnings.length, 1)
646
- assert.ok(
647
- result.warnings[0].startsWith('Unknown option: --sektion (ignored)'),
648
- `unexpected warning: ${result.warnings[0]}`
649
- )
650
- assert.strictEqual(result.options.sektion, 'functions')
651
- assert.strictEqual(result.options.section, 'all')
652
- })
653
-
654
- test('warns on an unknown --opt=value option', () => {
655
- const result = parseCLIArguments(
656
- ['list', '--sektion=functions'],
657
- 'test-cli',
658
- listMeta
659
- )
660
-
661
- assert.strictEqual(result.errors.length, 0)
662
- assert.strictEqual(result.warnings.length, 1)
663
- assert.ok(
664
- result.warnings[0].startsWith('Unknown option: --sektion (ignored)'),
665
- `unexpected warning: ${result.warnings[0]}`
666
- )
667
- assert.strictEqual(result.options.sektion, 'functions')
668
- })
669
-
670
- test('suggests a near-miss option name', () => {
671
- const result = parseCLIArguments(
672
- ['list', '--sektion'],
673
- 'test-cli',
674
- listMeta
675
- )
676
-
677
- assert.ok(
678
- result.warnings[0].includes('Did you mean --section?'),
679
- `expected a suggestion, got: ${result.warnings[0]}`
680
- )
681
- })
682
-
683
- test('suggests the kebab-case rendering of a camelCase option', () => {
684
- const result = parseCLIArguments(
685
- ['list', '--auto-aply'],
686
- 'test-cli',
687
- listMeta
688
- )
689
-
690
- assert.ok(
691
- result.warnings[0].includes('Did you mean --auto-apply?'),
692
- `expected a suggestion, got: ${result.warnings[0]}`
693
- )
694
- })
695
-
696
- test('omits the suggestion when nothing is close', () => {
697
- const result = parseCLIArguments(
698
- ['list', '--completely-different'],
699
- 'test-cli',
700
- listMeta
701
- )
702
-
703
- assert.strictEqual(
704
- result.warnings[0],
705
- 'Unknown option: --completely-different (ignored)'
706
- )
707
- })
708
-
709
- test('does not warn for a known option (either casing)', () => {
710
- const kebab = parseCLIArguments(
711
- ['list', '--section', 'functions', '--auto-apply'],
712
- 'test-cli',
713
- listMeta
714
- )
715
- assert.deepStrictEqual(kebab.warnings, [])
716
- assert.strictEqual(kebab.options.section, 'functions')
717
-
718
- const camel = parseCLIArguments(
719
- ['list', '--autoApply'],
720
- 'test-cli',
721
- listMeta
722
- )
723
- assert.deepStrictEqual(camel.warnings, [])
724
- })
725
-
726
- test('does not warn for --help', () => {
727
- const result = parseCLIArguments(['list', '--help'], 'test-cli', listMeta)
728
-
729
- assert.deepStrictEqual(result.warnings, [])
730
- })
731
-
732
- test('unknown short flags still error, not warn', () => {
733
- const result = parseCLIArguments(['list', '-x'], 'test-cli', listMeta)
734
-
735
- assert.ok(result.errors.some((e) => e.includes('Unknown option: -x')))
736
- assert.deepStrictEqual(result.warnings, [])
737
- })
738
- describe('short-flag cluster is bounded (DoS)', () => {
739
- test('a huge short-flag cluster yields a single error, not one per char', () => {
740
- const huge = '-' + 'a'.repeat(200_000)
741
- const result = parseCLIArguments(
742
- ['greet', 'Alice', huge],
743
- 'test-cli',
744
- testMeta
745
- )
746
- const clusterErrors = result.errors.filter((e) =>
747
- e.includes('Unknown option')
748
- )
749
- // Without the cap this would be ~200k errors (one per character).
750
- assert.ok(
751
- clusterErrors.length <= 2,
752
- `expected the oversized cluster to collapse to a single error, got ${clusterErrors.length}`
753
- )
754
- assert.ok(result.errors.some((e) => e.includes('too long')))
755
- })
756
- })
757
- })
758
-
759
- describe('the option spec drives value consumption', () => {
760
- test('a string option takes the next token verbatim, even leading with a dash', () => {
761
- const result = parseCLIArguments(
762
- ['deploy', '--token', '-PumP_kL0'],
763
- 'test-cli',
764
- testMeta
765
- )
766
-
767
- assert.deepStrictEqual(result.errors, [])
768
- assert.strictEqual(result.options.token, '-PumP_kL0')
769
- })
770
-
771
- test('an untyped option with no boolean/number default is still a string', () => {
772
- const result = parseCLIArguments(
773
- ['deploy', '--note', '-dash-leading'],
774
- 'test-cli',
775
- testMeta
776
- )
777
-
778
- assert.deepStrictEqual(result.errors, [])
779
- assert.strictEqual(result.options.note, '-dash-leading')
780
- })
781
-
782
- test('a comma list into an array option splits, trims and drops blanks', () => {
783
- const result = parseCLIArguments(
784
- ['deploy', '--tags', 'alpha, beta ,,gamma'],
785
- 'test-cli',
786
- testMeta
787
- )
788
-
789
- assert.deepStrictEqual(result.errors, [])
790
- assert.deepStrictEqual(result.options.tags, ['alpha', 'beta', 'gamma'])
791
- })
792
-
793
- test('an array option splits the --opt=value form too', () => {
794
- const result = parseCLIArguments(
795
- ['deploy', '--tags=alpha,beta'],
796
- 'test-cli',
797
- testMeta
798
- )
799
-
800
- assert.deepStrictEqual(result.options.tags, ['alpha', 'beta'])
801
- })
802
-
803
- test('an array option consumes exactly one token', () => {
804
- const result = parseCLIArguments(
805
- ['deploy', '--tags', 'alpha,beta', '--note', 'hello'],
806
- 'test-cli',
807
- testMeta
808
- )
809
-
810
- assert.deepStrictEqual(result.errors, [])
811
- assert.deepStrictEqual(result.options.tags, ['alpha', 'beta'])
812
- assert.strictEqual(result.options.note, 'hello')
813
- })
814
-
815
- /**
816
- * `--tags alpha beta` cannot be told apart from an option followed by a
817
- * positional, so consuming tokens until the next flag would make an array
818
- * option swallow arguments meant for the command. The two unambiguous
819
- * forms — one comma list, or the flag repeated — cover the same ground,
820
- * and the leftover token is reported rather than silently dropped.
821
- */
822
- test('an array option leaves a following bare token to the positionals', () => {
823
- const result = parseCLIArguments(
824
- ['deploy', '--tags', 'alpha', 'beta'],
825
- 'test-cli',
826
- testMeta
827
- )
828
-
829
- assert.deepStrictEqual(result.options.tags, ['alpha'])
830
- assert.ok(
831
- result.errors.some((error) => error.includes('Unexpected arguments')),
832
- `expected the stray token to be reported, got: ${JSON.stringify(result.errors)}`
833
- )
834
- })
835
-
836
- test('a repeated array option accumulates', () => {
837
- const result = parseCLIArguments(
838
- ['deploy', '--tags', 'alpha', '--tags', 'beta,gamma'],
839
- 'test-cli',
840
- testMeta
841
- )
842
-
843
- assert.deepStrictEqual(result.options.tags, ['alpha', 'beta', 'gamma'])
844
- })
845
-
846
- test('an array option takes a dash-leading value verbatim', () => {
847
- const result = parseCLIArguments(
848
- ['deploy', '--tags', '-alpha,beta'],
849
- 'test-cli',
850
- testMeta
851
- )
852
-
853
- assert.deepStrictEqual(result.errors, [])
854
- assert.deepStrictEqual(result.options.tags, ['-alpha', 'beta'])
855
- })
856
-
857
- test('a comma in a non-array option stays one literal string', () => {
858
- const result = parseCLIArguments(
859
- ['deploy', '--note', 'alpha,beta'],
860
- 'test-cli',
861
- testMeta
862
- )
863
-
864
- assert.strictEqual(result.options.note, 'alpha,beta')
865
- })
866
-
867
- test('a boolean option does not consume a following non-literal token', () => {
868
- const result = parseCLIArguments(
869
- ['deploy', '--dry-run', '--note', 'hello'],
870
- 'test-cli',
871
- testMeta
872
- )
873
-
874
- assert.deepStrictEqual(result.errors, [])
875
- assert.strictEqual(result.options.dryRun, true)
876
- assert.strictEqual(result.options.note, 'hello')
877
- })
878
-
879
- test('boolean options take an explicit literal instead of leaking positionals', () => {
880
- const devMeta: CLIMeta = {
881
- programs: {
882
- 'dev-cli': {
883
- program: 'dev-cli',
884
- options: {},
885
- commands: {
886
- dev: {
887
- pikkuFuncId: 'devFunc',
888
- positionals: [],
889
- options: {
890
- port: {
891
- description: 'Port for the dev server',
892
- default: '3000',
893
- short: 'p',
894
- },
895
- watch: {
896
- description: 'Watch for file changes and regenerate',
897
- default: true,
898
- },
899
- hmr: {
900
- description: 'Enable hot module reload',
901
- default: true,
902
- },
903
- },
904
- },
905
- },
906
- },
907
- },
908
- renderers: {},
909
- }
910
-
911
- const result = parseCLIArguments(
912
- ['dev', '--port', '4077', '--watch', 'false', '--hmr', 'false'],
913
- 'dev-cli',
914
- devMeta
915
- )
916
-
917
- assert.deepStrictEqual(result.errors, [])
918
- assert.deepStrictEqual(result.positionals, {})
919
- assert.strictEqual(result.options.port, '4077')
920
- assert.strictEqual(result.options.watch, false)
921
- assert.strictEqual(result.options.hmr, false)
922
- })
923
-
924
- test('a typed boolean option with no default takes an explicit literal', () => {
925
- const result = parseCLIArguments(
926
- ['deploy', '--dry-run', 'false', '--note', 'hello'],
927
- 'test-cli',
928
- testMeta
929
- )
930
-
931
- assert.deepStrictEqual(result.errors, [])
932
- assert.strictEqual(result.options.dryRun, false)
933
- assert.strictEqual(result.options.note, 'hello')
934
- })
935
-
936
- test('a boolean option takes an explicit literal in the --opt=value form', () => {
937
- const result = parseCLIArguments(
938
- ['deploy', '--dry-run=false'],
939
- 'test-cli',
940
- testMeta
941
- )
942
-
943
- assert.deepStrictEqual(result.errors, [])
944
- assert.strictEqual(result.options.dryRun, false)
945
- })
946
-
947
- test('a boolean short flag takes an explicit literal', () => {
948
- const result = parseCLIArguments(
949
- ['deploy', '-D', 'false'],
950
- 'test-cli',
951
- testMeta
952
- )
953
-
954
- assert.deepStrictEqual(result.errors, [])
955
- assert.strictEqual(result.options.dryRun, false)
956
- })
957
-
958
- test('a short flag follows its option spec for dash-leading values', () => {
959
- const result = parseCLIArguments(
960
- ['deploy', '-k', '-PumP_kL0'],
961
- 'test-cli',
962
- testMeta
963
- )
964
-
965
- assert.deepStrictEqual(result.errors, [])
966
- assert.strictEqual(result.options.token, '-PumP_kL0')
967
- })
968
-
969
- test('a short flag for an array option splits on commas', () => {
970
- const result = parseCLIArguments(
971
- ['deploy', '-t', 'alpha,beta'],
972
- 'test-cli',
973
- testMeta
974
- )
975
-
976
- assert.deepStrictEqual(result.options.tags, ['alpha', 'beta'])
977
- })
978
-
979
- test('a boolean short flag in a cluster does not swallow the next token', () => {
980
- const result = parseCLIArguments(
981
- ['deploy', '-D', 'positional-would-error'],
982
- 'test-cli',
983
- testMeta
984
- )
985
-
986
- assert.strictEqual(result.options.dryRun, true)
987
- assert.ok(
988
- result.errors.some((e) => e.includes('Unexpected arguments')),
989
- `expected the token to stay a positional, got: ${result.errors.join(', ')}`
990
- )
991
- })
992
- })
993
- })
994
-
995
- describe('option types come from the function input schema', () => {
996
- const schemaMeta: CLIMeta = {
997
- programs: {
998
- 'test-cli': {
999
- program: 'test-cli',
1000
- options: {},
1001
- commands: {
1002
- serve: {
1003
- pikkuFuncId: 'serveFunc',
1004
- positionals: [],
1005
- options: {
1006
- console: { description: 'Serve the console' },
1007
- port: { description: 'Port to listen on' },
1008
- tags: { description: 'Tags to include' },
1009
- retries: { description: 'How many times to retry' },
1010
- declared: {
1011
- description: 'Declared against the schema',
1012
- type: 'string',
1013
- },
1014
- },
1015
- },
1016
- },
1017
- },
1018
- },
1019
- renderers: {},
1020
- }
1021
-
1022
- const registerSchema = (properties: Record<string, unknown>) => {
1023
- pikkuState(null, 'function', 'meta')['serveFunc'] = {
1024
- pikkuFuncId: 'serveFunc',
1025
- inputSchemaName: 'ServeInput',
1026
- outputSchemaName: null,
1027
- sessionless: true,
1028
- } as any
1029
- pikkuState(null, 'misc', 'schemas').set('ServeInput', {
1030
- type: 'object',
1031
- properties,
1032
- })
1033
- }
1034
-
1035
- beforeEach(() => {
1036
- resetPikkuState()
1037
- registerSchema({
1038
- console: { type: 'boolean' },
1039
- port: { type: 'string' },
1040
- tags: { type: 'array', items: { type: 'string' } },
1041
- retries: { type: 'number' },
1042
- declared: { type: 'boolean' },
1043
- })
1044
- })
1045
-
1046
- after(() => {
1047
- resetPikkuState()
1048
- })
1049
-
1050
- test('a boolean in the schema is a flag, and does not swallow the next option', () => {
1051
- const result = parseCLIArguments(
1052
- ['serve', '--console', '--port', '4077'],
1053
- 'test-cli',
1054
- schemaMeta
1055
- )
1056
-
1057
- assert.deepStrictEqual(result.errors, [])
1058
- assert.strictEqual(result.options.console, true)
1059
- assert.strictEqual(result.options.port, '4077')
1060
- })
1061
-
1062
- test('an array in the schema splits on commas without being declared', () => {
1063
- const result = parseCLIArguments(
1064
- ['serve', '--tags', 'alpha,beta'],
1065
- 'test-cli',
1066
- schemaMeta
1067
- )
1068
-
1069
- assert.deepStrictEqual(result.options.tags, ['alpha', 'beta'])
1070
- })
1071
-
1072
- test('a number in the schema is coerced', () => {
1073
- const result = parseCLIArguments(
1074
- ['serve', '--retries', '3'],
1075
- 'test-cli',
1076
- schemaMeta
1077
- )
1078
-
1079
- assert.strictEqual(result.options.retries, 3)
1080
- })
1081
-
1082
- test('a declared type wins over the schema', () => {
1083
- const result = parseCLIArguments(
1084
- ['serve', '--declared', 'true'],
1085
- 'test-cli',
1086
- schemaMeta
1087
- )
1088
-
1089
- assert.strictEqual(result.options.declared, 'true')
1090
- })
1091
-
1092
- test('an option the schema does not mention keeps the string default', () => {
1093
- registerSchema({ console: { type: 'boolean' } })
1094
-
1095
- const result = parseCLIArguments(
1096
- ['serve', '--port', '4077'],
1097
- 'test-cli',
1098
- schemaMeta
1099
- )
1100
-
1101
- assert.strictEqual(result.options.port, '4077')
1102
- })
1103
-
1104
- test('a command with no input schema parses as it did before', () => {
1105
- pikkuState(null, 'function', 'meta')['serveFunc'] = {
1106
- pikkuFuncId: 'serveFunc',
1107
- inputSchemaName: null,
1108
- outputSchemaName: null,
1109
- sessionless: true,
1110
- } as any
1111
-
1112
- const result = parseCLIArguments(
1113
- ['serve', '--tags', 'alpha,beta'],
1114
- 'test-cli',
1115
- schemaMeta
1116
- )
1117
-
1118
- assert.strictEqual(result.options.tags, 'alpha,beta')
1119
- })
1120
- })