padrone 1.8.2 → 2.0.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 (333) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/README.md +2 -2
  3. package/dist/codegen/code-builder.d.mts +10 -0
  4. package/dist/codegen/code-builder.d.mts.map +1 -0
  5. package/dist/codegen/code-builder.mjs +185 -0
  6. package/dist/codegen/code-builder.mjs.map +1 -0
  7. package/dist/codegen/discovery.d.mts +44 -0
  8. package/dist/codegen/discovery.d.mts.map +1 -0
  9. package/dist/codegen/discovery.mjs +179 -0
  10. package/dist/codegen/discovery.mjs.map +1 -0
  11. package/dist/codegen/file-emitter.d.mts +10 -0
  12. package/dist/codegen/file-emitter.d.mts.map +1 -0
  13. package/dist/codegen/file-emitter.mjs +58 -0
  14. package/dist/codegen/file-emitter.mjs.map +1 -0
  15. package/dist/codegen/generators/barrel-file.d.mts +10 -0
  16. package/dist/codegen/generators/barrel-file.d.mts.map +1 -0
  17. package/dist/codegen/generators/barrel-file.mjs +16 -0
  18. package/dist/codegen/generators/barrel-file.mjs.map +1 -0
  19. package/dist/codegen/generators/command-file.d.mts +25 -0
  20. package/dist/codegen/generators/command-file.d.mts.map +1 -0
  21. package/dist/codegen/generators/command-file.mjs +130 -0
  22. package/dist/codegen/generators/command-file.mjs.map +1 -0
  23. package/dist/codegen/generators/command-tree.d.mts +17 -0
  24. package/dist/codegen/generators/command-tree.d.mts.map +1 -0
  25. package/dist/codegen/generators/command-tree.mjs +72 -0
  26. package/dist/codegen/generators/command-tree.mjs.map +1 -0
  27. package/dist/codegen/index.d.mts +15 -330
  28. package/dist/codegen/index.mjs +13 -1507
  29. package/dist/codegen/parsers/bash.d.mts +19 -0
  30. package/dist/codegen/parsers/bash.d.mts.map +1 -0
  31. package/dist/codegen/parsers/bash.mjs +112 -0
  32. package/dist/codegen/parsers/bash.mjs.map +1 -0
  33. package/dist/codegen/parsers/fish.d.mts +13 -0
  34. package/dist/codegen/parsers/fish.d.mts.map +1 -0
  35. package/dist/codegen/parsers/fish.mjs +108 -0
  36. package/dist/codegen/parsers/fish.mjs.map +1 -0
  37. package/dist/codegen/parsers/help.d.mts +15 -0
  38. package/dist/codegen/parsers/help.d.mts.map +1 -0
  39. package/dist/codegen/parsers/help.mjs +271 -0
  40. package/dist/codegen/parsers/help.mjs.map +1 -0
  41. package/dist/codegen/parsers/merge.d.mts +14 -0
  42. package/dist/codegen/parsers/merge.d.mts.map +1 -0
  43. package/dist/codegen/parsers/merge.mjs +76 -0
  44. package/dist/codegen/parsers/merge.mjs.map +1 -0
  45. package/dist/codegen/parsers/zsh.d.mts +16 -0
  46. package/dist/codegen/parsers/zsh.d.mts.map +1 -0
  47. package/dist/codegen/parsers/zsh.mjs +161 -0
  48. package/dist/codegen/parsers/zsh.mjs.map +1 -0
  49. package/dist/codegen/schema-to-code.d.mts +24 -0
  50. package/dist/codegen/schema-to-code.d.mts.map +1 -0
  51. package/dist/codegen/schema-to-code.mjs +147 -0
  52. package/dist/codegen/schema-to-code.mjs.map +1 -0
  53. package/dist/codegen/template.d.mts +18 -0
  54. package/dist/codegen/template.d.mts.map +1 -0
  55. package/dist/codegen/template.mjs +37 -0
  56. package/dist/codegen/template.mjs.map +1 -0
  57. package/dist/codegen/types.d.mts +144 -0
  58. package/dist/codegen/types.d.mts.map +1 -0
  59. package/dist/completion.d.mts +2 -0
  60. package/dist/completion.mjs +2 -0
  61. package/dist/core/args.d.mts +3 -0
  62. package/dist/{args-DrCXxXeP.mjs → core/args.mjs} +49 -113
  63. package/dist/core/args.mjs.map +1 -0
  64. package/dist/core/commands.d.mts +13 -0
  65. package/dist/core/commands.d.mts.map +1 -0
  66. package/dist/{commands-DLR0rFgq.mjs → core/commands.mjs} +4 -232
  67. package/dist/core/commands.mjs.map +1 -0
  68. package/dist/core/create.d.mts +63 -0
  69. package/dist/core/create.d.mts.map +1 -0
  70. package/dist/core/create.mjs +230 -0
  71. package/dist/core/create.mjs.map +1 -0
  72. package/dist/core/default-runtime.mjs +198 -0
  73. package/dist/core/default-runtime.mjs.map +1 -0
  74. package/dist/core/errors.d.mts +107 -0
  75. package/dist/core/errors.d.mts.map +1 -0
  76. package/dist/{errors-DA4KzK1M.mjs → core/errors.mjs} +2 -2
  77. package/dist/core/errors.mjs.map +1 -0
  78. package/dist/core/exec.mjs +191 -0
  79. package/dist/core/exec.mjs.map +1 -0
  80. package/dist/core/interceptors.d.mts +33 -0
  81. package/dist/core/interceptors.d.mts.map +1 -0
  82. package/dist/core/interceptors.mjs +253 -0
  83. package/dist/core/interceptors.mjs.map +1 -0
  84. package/dist/core/parse.mjs +181 -0
  85. package/dist/core/parse.mjs.map +1 -0
  86. package/dist/core/program-methods.mjs +256 -0
  87. package/dist/core/program-methods.mjs.map +1 -0
  88. package/dist/core/results.d.mts +13 -0
  89. package/dist/core/results.d.mts.map +1 -0
  90. package/dist/core/results.mjs +150 -0
  91. package/dist/core/results.mjs.map +1 -0
  92. package/dist/core/runtime.d.mts +213 -0
  93. package/dist/core/runtime.d.mts.map +1 -0
  94. package/dist/core/runtime.mjs +10 -0
  95. package/dist/core/runtime.mjs.map +1 -0
  96. package/dist/core/validate.mjs +220 -0
  97. package/dist/core/validate.mjs.map +1 -0
  98. package/dist/docs/index.d.mts +1 -1
  99. package/dist/docs/index.d.mts.map +1 -1
  100. package/dist/docs/index.mjs +2 -2
  101. package/dist/docs/index.mjs.map +1 -1
  102. package/dist/extension/auto-output.d.mts +53 -0
  103. package/dist/extension/auto-output.d.mts.map +1 -0
  104. package/dist/extension/auto-output.mjs +116 -0
  105. package/dist/extension/auto-output.mjs.map +1 -0
  106. package/dist/extension/color.d.mts +19 -0
  107. package/dist/extension/color.d.mts.map +1 -0
  108. package/dist/extension/color.mjs +37 -0
  109. package/dist/extension/color.mjs.map +1 -0
  110. package/dist/extension/completion.d.mts +25 -0
  111. package/dist/extension/completion.d.mts.map +1 -0
  112. package/dist/extension/completion.mjs +40 -0
  113. package/dist/extension/completion.mjs.map +1 -0
  114. package/dist/extension/config.d.mts +55 -0
  115. package/dist/extension/config.d.mts.map +1 -0
  116. package/dist/extension/config.mjs +162 -0
  117. package/dist/extension/config.mjs.map +1 -0
  118. package/dist/extension/env.d.mts +42 -0
  119. package/dist/extension/env.d.mts.map +1 -0
  120. package/dist/extension/env.mjs +44 -0
  121. package/dist/extension/env.mjs.map +1 -0
  122. package/dist/extension/help.d.mts +29 -0
  123. package/dist/extension/help.d.mts.map +1 -0
  124. package/dist/extension/help.mjs +161 -0
  125. package/dist/extension/help.mjs.map +1 -0
  126. package/dist/extension/index.d.mts +18 -0
  127. package/dist/extension/ink.d.mts +31 -0
  128. package/dist/extension/ink.d.mts.map +1 -0
  129. package/dist/extension/ink.mjs +69 -0
  130. package/dist/extension/ink.mjs.map +1 -0
  131. package/dist/extension/interactive.d.mts +16 -0
  132. package/dist/extension/interactive.d.mts.map +1 -0
  133. package/dist/extension/interactive.mjs +89 -0
  134. package/dist/extension/interactive.mjs.map +1 -0
  135. package/dist/extension/logger.d.mts +67 -0
  136. package/dist/extension/logger.d.mts.map +1 -0
  137. package/dist/extension/logger.mjs +188 -0
  138. package/dist/extension/logger.mjs.map +1 -0
  139. package/dist/extension/man.d.mts +25 -0
  140. package/dist/extension/man.d.mts.map +1 -0
  141. package/dist/extension/man.mjs +41 -0
  142. package/dist/extension/man.mjs.map +1 -0
  143. package/dist/extension/mcp.d.mts +28 -0
  144. package/dist/extension/mcp.d.mts.map +1 -0
  145. package/dist/extension/mcp.mjs +44 -0
  146. package/dist/extension/mcp.mjs.map +1 -0
  147. package/dist/extension/progress-renderer.d.mts +13 -0
  148. package/dist/extension/progress-renderer.d.mts.map +1 -0
  149. package/dist/extension/progress-renderer.mjs +351 -0
  150. package/dist/extension/progress-renderer.mjs.map +1 -0
  151. package/dist/extension/progress.d.mts +76 -0
  152. package/dist/extension/progress.d.mts.map +1 -0
  153. package/dist/extension/progress.mjs +225 -0
  154. package/dist/extension/progress.mjs.map +1 -0
  155. package/dist/extension/repl.d.mts +26 -0
  156. package/dist/extension/repl.d.mts.map +1 -0
  157. package/dist/extension/repl.mjs +67 -0
  158. package/dist/extension/repl.mjs.map +1 -0
  159. package/dist/extension/serve.d.mts +27 -0
  160. package/dist/extension/serve.d.mts.map +1 -0
  161. package/dist/extension/serve.mjs +41 -0
  162. package/dist/extension/serve.mjs.map +1 -0
  163. package/dist/extension/signal.d.mts +19 -0
  164. package/dist/extension/signal.d.mts.map +1 -0
  165. package/dist/extension/signal.mjs +81 -0
  166. package/dist/extension/signal.mjs.map +1 -0
  167. package/dist/extension/stdin.d.mts +19 -0
  168. package/dist/extension/stdin.d.mts.map +1 -0
  169. package/dist/extension/stdin.mjs +52 -0
  170. package/dist/extension/stdin.mjs.map +1 -0
  171. package/dist/extension/suggestions.d.mts +6 -0
  172. package/dist/extension/suggestions.d.mts.map +1 -0
  173. package/dist/extension/suggestions.mjs +113 -0
  174. package/dist/extension/suggestions.mjs.map +1 -0
  175. package/dist/extension/timing.d.mts +27 -0
  176. package/dist/extension/timing.d.mts.map +1 -0
  177. package/dist/extension/timing.mjs +71 -0
  178. package/dist/extension/timing.mjs.map +1 -0
  179. package/dist/extension/tracing.d.mts +85 -0
  180. package/dist/extension/tracing.d.mts.map +1 -0
  181. package/dist/extension/tracing.mjs +107 -0
  182. package/dist/extension/tracing.mjs.map +1 -0
  183. package/dist/extension/update-check.d.mts +20 -0
  184. package/dist/extension/update-check.d.mts.map +1 -0
  185. package/dist/extension/update-check.mjs +62 -0
  186. package/dist/extension/update-check.mjs.map +1 -0
  187. package/dist/extension/utils.mjs +43 -0
  188. package/dist/extension/utils.mjs.map +1 -0
  189. package/dist/extension/version.d.mts +20 -0
  190. package/dist/extension/version.d.mts.map +1 -0
  191. package/dist/extension/version.mjs +51 -0
  192. package/dist/extension/version.mjs.map +1 -0
  193. package/dist/{completion-UnBKfGuk.mjs → feature/completion.mjs} +4 -3
  194. package/dist/feature/completion.mjs.map +1 -0
  195. package/dist/feature/interactive.mjs +145 -0
  196. package/dist/feature/interactive.mjs.map +1 -0
  197. package/dist/feature/mcp.d.mts +18 -0
  198. package/dist/feature/mcp.d.mts.map +1 -0
  199. package/dist/{mcp-D6PdtjIs.mjs → feature/mcp.mjs} +6 -6
  200. package/dist/feature/mcp.mjs.map +1 -0
  201. package/dist/feature/repl-loop.mjs +217 -0
  202. package/dist/feature/repl-loop.mjs.map +1 -0
  203. package/dist/feature/serve.d.mts +18 -0
  204. package/dist/feature/serve.d.mts.map +1 -0
  205. package/dist/{serve-PaCLsNoD.mjs → feature/serve.mjs} +7 -7
  206. package/dist/feature/serve.mjs.map +1 -0
  207. package/dist/feature/test.d.mts +109 -0
  208. package/dist/feature/test.d.mts.map +1 -0
  209. package/dist/feature/test.mjs +116 -0
  210. package/dist/feature/test.mjs.map +1 -0
  211. package/dist/feature/update-check.d.mts +35 -0
  212. package/dist/feature/update-check.d.mts.map +1 -0
  213. package/dist/{update-check-CZ2VqjnV.mjs → feature/update-check.mjs} +2 -2
  214. package/dist/feature/update-check.mjs.map +1 -0
  215. package/dist/feature/wrap.d.mts +58 -0
  216. package/dist/feature/wrap.d.mts.map +1 -0
  217. package/dist/feature/wrap.mjs +77 -0
  218. package/dist/feature/wrap.mjs.map +1 -0
  219. package/dist/index.d.mts +38 -901
  220. package/dist/index.mjs +25 -4337
  221. package/dist/ink.d.mts +2 -0
  222. package/dist/ink.mjs +2 -0
  223. package/dist/man.d.mts +2 -0
  224. package/dist/man.mjs +2 -0
  225. package/dist/mcp.d.mts +3 -0
  226. package/dist/mcp.mjs +2 -0
  227. package/dist/output/colorizer.d.mts +28 -0
  228. package/dist/output/colorizer.d.mts.map +1 -0
  229. package/dist/output/colorizer.mjs +94 -0
  230. package/dist/output/colorizer.mjs.map +1 -0
  231. package/dist/{formatter-CY3KrOEd.d.mts → output/formatter.d.mts} +2 -28
  232. package/dist/output/formatter.d.mts.map +1 -0
  233. package/dist/output/formatter.mjs +360 -0
  234. package/dist/output/formatter.mjs.map +1 -0
  235. package/dist/output/help.d.mts +18 -0
  236. package/dist/output/help.d.mts.map +1 -0
  237. package/dist/output/help.mjs +267 -0
  238. package/dist/output/help.mjs.map +1 -0
  239. package/dist/output/output-indicator.d.mts +27 -0
  240. package/dist/output/output-indicator.d.mts.map +1 -0
  241. package/dist/output/output-indicator.mjs +54 -0
  242. package/dist/output/output-indicator.mjs.map +1 -0
  243. package/dist/output/primitives.d.mts +33 -0
  244. package/dist/output/primitives.d.mts.map +1 -0
  245. package/dist/output/primitives.mjs +206 -0
  246. package/dist/output/primitives.mjs.map +1 -0
  247. package/dist/output/styling.d.mts +38 -0
  248. package/dist/output/styling.d.mts.map +1 -0
  249. package/dist/output/styling.mjs +146 -0
  250. package/dist/output/styling.mjs.map +1 -0
  251. package/dist/schema/zod.d.mts +6 -0
  252. package/dist/schema/zod.d.mts.map +1 -0
  253. package/dist/schema/zod.mjs +50 -0
  254. package/dist/schema/zod.mjs.map +1 -0
  255. package/dist/serve.d.mts +2 -0
  256. package/dist/serve.mjs +2 -0
  257. package/dist/test.d.mts +2 -109
  258. package/dist/test.mjs +1 -115
  259. package/dist/tracing.d.mts +2 -0
  260. package/dist/tracing.mjs +2 -0
  261. package/dist/types/args-meta.d.mts +129 -0
  262. package/dist/types/args-meta.d.mts.map +1 -0
  263. package/dist/types/builder.d.mts +212 -0
  264. package/dist/types/builder.d.mts.map +1 -0
  265. package/dist/types/command.d.mts +112 -0
  266. package/dist/types/command.d.mts.map +1 -0
  267. package/dist/types/index.d.mts +8 -0
  268. package/dist/types/interceptor.d.mts +232 -0
  269. package/dist/types/interceptor.d.mts.map +1 -0
  270. package/dist/types/preferences.d.mts +79 -0
  271. package/dist/types/preferences.d.mts.map +1 -0
  272. package/dist/types/result.d.mts +61 -0
  273. package/dist/types/result.d.mts.map +1 -0
  274. package/dist/types/schema.d.mts +24 -0
  275. package/dist/types/schema.d.mts.map +1 -0
  276. package/dist/util/dotenv.mjs +174 -0
  277. package/dist/util/dotenv.mjs.map +1 -0
  278. package/dist/util/shell-utils.mjs +80 -0
  279. package/dist/util/shell-utils.mjs.map +1 -0
  280. package/dist/util/stream.d.mts +33 -0
  281. package/dist/util/stream.d.mts.map +1 -0
  282. package/dist/{stream-DC4H8YTx.mjs → util/stream.mjs} +2 -2
  283. package/dist/util/stream.mjs.map +1 -0
  284. package/dist/util/type-helpers.d.mts +74 -0
  285. package/dist/util/type-helpers.d.mts.map +1 -0
  286. package/dist/util/type-utils.d.mts +186 -0
  287. package/dist/util/type-utils.d.mts.map +1 -0
  288. package/dist/util/utils.mjs +43 -0
  289. package/dist/util/utils.mjs.map +1 -0
  290. package/dist/zod.d.mts +1 -32
  291. package/dist/zod.mjs +1 -49
  292. package/package.json +65 -17
  293. package/src/completion.ts +2 -0
  294. package/src/core/args.ts +63 -37
  295. package/src/core/runtime.ts +11 -2
  296. package/src/extension/completion.ts +3 -0
  297. package/src/extension/index.ts +0 -12
  298. package/src/extension/ink.ts +2 -1
  299. package/src/extension/man.ts +3 -0
  300. package/src/extension/mcp.ts +3 -0
  301. package/src/extension/progress-renderer.ts +32 -8
  302. package/src/extension/progress.ts +19 -9
  303. package/src/extension/serve.ts +3 -0
  304. package/src/extension/tracing.ts +2 -0
  305. package/src/index.ts +1 -20
  306. package/src/ink.ts +2 -0
  307. package/src/man.ts +2 -0
  308. package/src/mcp.ts +3 -0
  309. package/src/serve.ts +2 -0
  310. package/src/tracing.ts +9 -0
  311. package/src/types/builder.ts +2 -2
  312. package/src/zod.ts +1 -1
  313. package/dist/args-DrCXxXeP.mjs.map +0 -1
  314. package/dist/codegen/index.d.mts.map +0 -1
  315. package/dist/codegen/index.mjs.map +0 -1
  316. package/dist/commands-DLR0rFgq.mjs.map +0 -1
  317. package/dist/completion-UnBKfGuk.mjs.map +0 -1
  318. package/dist/errors-DA4KzK1M.mjs.map +0 -1
  319. package/dist/formatter-CY3KrOEd.d.mts.map +0 -1
  320. package/dist/help-B-ZMYyn-.mjs +0 -892
  321. package/dist/help-B-ZMYyn-.mjs.map +0 -1
  322. package/dist/index-D-Dpz7l_.d.mts +0 -1427
  323. package/dist/index-D-Dpz7l_.d.mts.map +0 -1
  324. package/dist/index.d.mts.map +0 -1
  325. package/dist/index.mjs.map +0 -1
  326. package/dist/mcp-D6PdtjIs.mjs.map +0 -1
  327. package/dist/serve-PaCLsNoD.mjs.map +0 -1
  328. package/dist/stream-DC4H8YTx.mjs.map +0 -1
  329. package/dist/test.d.mts.map +0 -1
  330. package/dist/test.mjs.map +0 -1
  331. package/dist/update-check-CZ2VqjnV.mjs.map +0 -1
  332. package/dist/zod.d.mts.map +0 -1
  333. package/dist/zod.mjs.map +0 -1
@@ -0,0 +1,225 @@
1
+ import { defineInterceptor } from "../core/interceptors.mjs";
2
+ import { createTerminalProgress } from "./progress-renderer.mjs";
3
+ //#region src/extension/progress.ts
4
+ const noopIndicator = {
5
+ update() {},
6
+ eta: {
7
+ start() {},
8
+ stop() {},
9
+ reset() {}
10
+ },
11
+ succeed() {},
12
+ fail() {},
13
+ stop() {},
14
+ pause() {},
15
+ resume() {}
16
+ };
17
+ function resolveMessage(field, value, fallback) {
18
+ const raw = typeof field === "function" ? field(value) : field;
19
+ if (raw === void 0) return { message: fallback };
20
+ if (raw === null || typeof raw === "string") return { message: raw };
21
+ if (typeof raw === "object" && raw !== null) {
22
+ const obj = raw;
23
+ return {
24
+ message: obj.message,
25
+ indicator: obj.indicator
26
+ };
27
+ }
28
+ return { message: fallback };
29
+ }
30
+ function cleanup(indicator, successConfig, errorConfig, error, result, isError) {
31
+ if (isError) {
32
+ const { message: errorMsg, indicator: errorIcon } = resolveMessage(errorConfig, error, error instanceof Error ? error.message : String(error));
33
+ indicator.fail(errorMsg, errorIcon !== void 0 ? { indicator: errorIcon } : void 0);
34
+ } else {
35
+ const { message: successMsg, indicator: successIcon } = resolveMessage(successConfig, result);
36
+ indicator.succeed(successMsg, successIcon !== void 0 ? { indicator: successIcon } : void 0);
37
+ }
38
+ }
39
+ function resolveMessages(raw) {
40
+ if (!raw || typeof raw === "string") return {
41
+ progress: raw || "Working...",
42
+ validation: "",
43
+ success: void 0,
44
+ error: void 0
45
+ };
46
+ return {
47
+ progress: raw.progress ?? "Working...",
48
+ validation: raw.validation ?? "",
49
+ success: raw.success,
50
+ error: raw.error
51
+ };
52
+ }
53
+ function mergeMessages(cmd, ctx, cmdRaw) {
54
+ if (typeof cmdRaw === "string") return cmd;
55
+ const obj = typeof cmdRaw === "object" ? cmdRaw : void 0;
56
+ return {
57
+ progress: obj?.progress !== void 0 ? cmd.progress : ctx.progress ?? cmd.progress,
58
+ validation: obj?.validation !== void 0 ? cmd.validation : ctx.validation || cmd.validation,
59
+ success: obj?.success !== void 0 ? cmd.success : ctx.success ?? cmd.success,
60
+ error: obj?.error !== void 0 ? cmd.error : ctx.error ?? cmd.error
61
+ };
62
+ }
63
+ function progressInterceptor(config) {
64
+ const isObj = typeof config === "object";
65
+ const rawMessage = typeof config === "string" ? config : isObj ? config.message : void 0;
66
+ const rawSpinner = isObj ? config.spinner : void 0;
67
+ const rawBar = isObj ? config.bar : void 0;
68
+ const rawRenderer = isObj ? config.renderer : void 0;
69
+ const rawTime = isObj ? config.time : void 0;
70
+ const rawEta = isObj ? config.eta : void 0;
71
+ const rawSilent = isObj ? config.silent : void 0;
72
+ return defineInterceptor({
73
+ id: "padrone:progress",
74
+ name: "padrone:progress"
75
+ }).requires().factory(() => {
76
+ let indicator;
77
+ let restoreOutput;
78
+ let resolvedRenderer;
79
+ let resolvedOptions;
80
+ let resolvedSilent = false;
81
+ let msgs;
82
+ function resolve(ctx) {
83
+ if (resolvedRenderer) return;
84
+ const ctxCfg = ctx.context?.progressConfig;
85
+ resolvedSilent = rawSilent ?? ctxCfg?.silent ?? false;
86
+ const spinner = rawSpinner ?? ctxCfg?.spinner;
87
+ const bar = rawBar ?? ctxCfg?.bar;
88
+ const time = rawTime ?? ctxCfg?.time;
89
+ const eta = rawEta ?? ctxCfg?.eta;
90
+ resolvedRenderer = rawRenderer ?? ctxCfg?.renderer ?? createTerminalProgress;
91
+ resolvedOptions = spinner !== void 0 || bar !== void 0 || time !== void 0 || eta !== void 0 ? {
92
+ spinner,
93
+ bar,
94
+ time,
95
+ eta
96
+ } : void 0;
97
+ msgs = mergeMessages(resolveMessages(rawMessage), resolveMessages(ctxCfg?.message), rawMessage);
98
+ }
99
+ const teardown = () => {
100
+ restoreOutput?.();
101
+ indicator = void 0;
102
+ restoreOutput = void 0;
103
+ };
104
+ return {
105
+ validate(ctx, next) {
106
+ resolve(ctx);
107
+ if (resolvedSilent) return next();
108
+ indicator = resolvedRenderer(msgs.validation || msgs.progress, resolvedOptions);
109
+ const originalOutput = ctx.runtime.output;
110
+ const originalError = ctx.runtime.error;
111
+ ctx.runtime.output = (...args) => {
112
+ indicator.pause();
113
+ originalOutput(...args);
114
+ indicator.resume();
115
+ };
116
+ ctx.runtime.error = (text) => {
117
+ indicator.pause();
118
+ originalError(text);
119
+ indicator.resume();
120
+ };
121
+ restoreOutput = () => {
122
+ ctx.runtime.output = originalOutput;
123
+ ctx.runtime.error = originalError;
124
+ };
125
+ const onValidationFailure = (error) => {
126
+ if (indicator) {
127
+ cleanup(indicator, msgs.success, msgs.error, error, void 0, true);
128
+ teardown();
129
+ }
130
+ };
131
+ const checkResult = (result) => {
132
+ if (result.argsResult?.issues) onValidationFailure(/* @__PURE__ */ new Error("Validation failed"));
133
+ return result;
134
+ };
135
+ let result;
136
+ try {
137
+ result = next();
138
+ } catch (err) {
139
+ onValidationFailure(err);
140
+ throw err;
141
+ }
142
+ if (result instanceof Promise) return result.then(checkResult, (err) => {
143
+ onValidationFailure(err);
144
+ throw err;
145
+ });
146
+ return checkResult(result);
147
+ },
148
+ execute(_ctx, next) {
149
+ if (resolvedSilent) return next({ context: { progress: noopIndicator } });
150
+ if (indicator && msgs.validation) indicator.update(msgs.progress);
151
+ const effectiveIndicator = indicator ?? noopIndicator;
152
+ const onSuccess = (value) => {
153
+ cleanup(effectiveIndicator, msgs.success, msgs.error, void 0, value, false);
154
+ teardown();
155
+ };
156
+ const onError = (err) => {
157
+ if (indicator) {
158
+ cleanup(indicator, msgs.success, msgs.error, err, void 0, true);
159
+ teardown();
160
+ }
161
+ throw err;
162
+ };
163
+ let result;
164
+ try {
165
+ result = next({ context: { progress: effectiveIndicator } });
166
+ } catch (err) {
167
+ onError(err);
168
+ }
169
+ if (result instanceof Promise) return result.then((r) => {
170
+ if (r.result instanceof Promise) return { result: r.result.then((value) => {
171
+ onSuccess(value);
172
+ return value;
173
+ }, (err) => onError(err)) };
174
+ onSuccess(r.result);
175
+ return r;
176
+ }, (err) => onError(err));
177
+ if (result.result instanceof Promise) return { result: result.result.then((value) => {
178
+ onSuccess(value);
179
+ return value;
180
+ }, (err) => onError(err)) };
181
+ onSuccess(result.result);
182
+ return result;
183
+ },
184
+ shutdown(ctx) {
185
+ if (indicator) {
186
+ cleanup(indicator, msgs.success, msgs.error, ctx.error, ctx.result, !!ctx.error);
187
+ teardown();
188
+ }
189
+ }
190
+ };
191
+ }).provides();
192
+ }
193
+ /**
194
+ * Extension that adds an auto-managed progress indicator to the command pipeline.
195
+ *
196
+ * - `string` — a single message used for all states.
197
+ * - `PadroneProgressConfig` — separate messages for validation, progress, success, and error.
198
+ *
199
+ * The indicator is automatically started before validation, updated at each phase transition,
200
+ * and stopped on success (`.succeed()`) or failure (`.fail()`).
201
+ *
202
+ * Provides `{ progress: PadroneProgress }` on the command context.
203
+ * Access it in action handlers as `ctx.context.progress`.
204
+ *
205
+ * Uses the built-in terminal renderer by default. Pass a custom `renderer` for non-terminal
206
+ * environments (web UIs, testing, etc).
207
+ *
208
+ * Usage:
209
+ * ```ts
210
+ * createPadrone('my-cli')
211
+ * .command('sync', (c) =>
212
+ * c.extend(padroneProgress('Syncing...'))
213
+ * .action((_args, ctx) => {
214
+ * ctx.context.progress.update('halfway');
215
+ * })
216
+ * )
217
+ * ```
218
+ */
219
+ function padroneProgress(config) {
220
+ return ((builder) => builder.intercept(progressInterceptor(config ?? "Working...")));
221
+ }
222
+ //#endregion
223
+ export { padroneProgress };
224
+
225
+ //# sourceMappingURL=progress.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.mjs","names":[],"sources":["../../src/extension/progress.ts"],"sourcesContent":["import { defineInterceptor } from '../core/interceptors.ts';\nimport type { PadroneBarConfig, PadroneProgress, PadroneProgressOptions, PadroneSpinnerConfig } from '../core/runtime.ts';\nimport type { AnyPadroneBuilder, CommandTypesBase } from '../types/index.ts';\nimport type { WithInterceptor } from '../util/type-utils.ts';\nimport type { PadroneProgressRenderer } from './progress-renderer.ts';\nimport { createTerminalProgress } from './progress-renderer.ts';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A progress message value: a plain string, `null` to suppress, or an object with a message and custom indicator icon. */\nexport type PadroneProgressMessage = string | null | { message?: string | null; indicator?: string };\n\n/** Per-phase message configuration for progress indicators. */\nexport type PadroneProgressMessages<TRes = unknown> = {\n /** Message shown during async validation. Defaults to `''` (spinner only). */\n validation?: string;\n /** Message shown while the command's action is running. */\n progress?: string;\n /** Message shown when the command succeeds. `null` to suppress. Defaults to the `progress` message. */\n success?: PadroneProgressMessage | ((result: TRes) => PadroneProgressMessage);\n /** Message shown when the command fails. `null` to suppress. Defaults to the error message. */\n error?: PadroneProgressMessage | ((error: unknown) => PadroneProgressMessage);\n};\n\n/**\n * Progress indicator configuration with messages, visual options, and renderer.\n */\nexport type PadroneProgressConfig<TRes = unknown> = {\n /** Per-phase messages. A string sets the `progress` message; an object configures individual phases. */\n message?: string | PadroneProgressMessages<TRes>;\n /** Spinner configuration. Default `show` is `'auto'` (visible when bar is not shown). `true` forces spinner to always show (even alongside a bar). */\n spinner?: PadroneSpinnerConfig;\n /** Enable a progress bar. `true` for defaults (`show: 'always'`), or a `PadroneBarConfig` object. `false` to disable entirely. When omitted, bar defaults to `show: 'auto'`. */\n bar?: boolean | PadroneBarConfig;\n /** Show elapsed time since the indicator started. Can also be started on demand via `update({ time: true })`. */\n time?: boolean;\n /** Show estimated time remaining based on progress rate. Requires numeric `update()` calls. */\n eta?: boolean;\n /**\n * Custom renderer factory. Called to create the progress indicator.\n * Defaults to the built-in terminal renderer (`createTerminalProgress`).\n */\n renderer?: PadroneProgressRenderer;\n /** Suppress all progress output. The `progress` interface is still provided on the context as a no-op. */\n silent?: boolean;\n};\n\n/**\n * Shared progress defaults that can be provided via context instead of repeating\n * at each call site. Per-instance message fields are excluded — those always come\n * from the constructor argument.\n *\n * Provide via context as `{ progressConfig: PadroneProgressDefaults }`.\n */\nexport type PadroneProgressDefaults = Pick<PadroneProgressConfig, 'message' | 'spinner' | 'bar' | 'time' | 'eta' | 'renderer' | 'silent'>;\n\n/** Builder/program type after applying `padroneProgress()`. Adds `{ progress: PadroneProgress }` to the command context. */\nexport type WithProgress<T> = WithInterceptor<T, { progress: PadroneProgress }>;\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst noopEta = { start() {}, stop() {}, reset() {} };\nconst noopIndicator: PadroneProgress = {\n update() {},\n eta: noopEta,\n succeed() {},\n fail() {},\n stop() {},\n pause() {},\n resume() {},\n};\n\nfunction resolveMessage(field: unknown, value: unknown, fallback?: string): { message: string | null | undefined; indicator?: string } {\n const raw = typeof field === 'function' ? (field as (v: unknown) => unknown)(value) : field;\n if (raw === undefined) return { message: fallback };\n if (raw === null || typeof raw === 'string') return { message: raw };\n if (typeof raw === 'object' && raw !== null) {\n const obj = raw as { message?: string | null; indicator?: string };\n return { message: obj.message, indicator: obj.indicator };\n }\n return { message: fallback };\n}\n\nfunction cleanup(\n indicator: PadroneProgress,\n successConfig: unknown,\n errorConfig: unknown,\n error: unknown,\n result: unknown,\n isError: boolean,\n) {\n if (isError) {\n const fallback = error instanceof Error ? error.message : String(error);\n const { message: errorMsg, indicator: errorIcon } = resolveMessage(errorConfig, error, fallback);\n indicator.fail(errorMsg, errorIcon !== undefined ? { indicator: errorIcon } : undefined);\n } else {\n const { message: successMsg, indicator: successIcon } = resolveMessage(successConfig, result);\n indicator.succeed(successMsg, successIcon !== undefined ? { indicator: successIcon } : undefined);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Interceptor\n// ---------------------------------------------------------------------------\n\nfunction resolveMessages(raw: string | PadroneProgressMessages | undefined): {\n progress: string;\n validation: string;\n success: unknown;\n error: unknown;\n} {\n if (!raw || typeof raw === 'string') {\n return { progress: raw || 'Working...', validation: '', success: undefined, error: undefined };\n }\n return {\n progress: raw.progress ?? 'Working...',\n validation: raw.validation ?? '',\n success: raw.success,\n error: raw.error,\n };\n}\n\nfunction mergeMessages(\n cmd: ReturnType<typeof resolveMessages>,\n ctx: ReturnType<typeof resolveMessages>,\n cmdRaw: string | PadroneProgressMessages | undefined,\n): ReturnType<typeof resolveMessages> {\n // String shorthand: all fields come from the string, no context fallback for individual fields\n if (typeof cmdRaw === 'string') return cmd;\n // Object: per-field fallback to context\n const obj = (typeof cmdRaw === 'object' ? cmdRaw : undefined) as PadroneProgressMessages | undefined;\n return {\n progress: obj?.progress !== undefined ? cmd.progress : (ctx.progress ?? cmd.progress),\n validation: obj?.validation !== undefined ? cmd.validation : ctx.validation || cmd.validation,\n success: obj?.success !== undefined ? cmd.success : (ctx.success ?? cmd.success),\n error: obj?.error !== undefined ? cmd.error : (ctx.error ?? cmd.error),\n };\n}\n\nfunction progressInterceptor(config: string | PadroneProgressConfig) {\n const isObj = typeof config === 'object';\n const rawMessage = typeof config === 'string' ? config : isObj ? config.message : undefined;\n // Raw constructor values — undefined means \"not set by caller\"\n const rawSpinner = isObj ? config.spinner : undefined;\n const rawBar = isObj ? config.bar : undefined;\n const rawRenderer = isObj ? config.renderer : undefined;\n const rawTime = isObj ? config.time : undefined;\n const rawEta = isObj ? config.eta : undefined;\n const rawSilent = isObj ? config.silent : undefined;\n\n return defineInterceptor({ id: 'padrone:progress', name: 'padrone:progress' })\n .requires<{ progressConfig?: PadroneProgressDefaults }>()\n .factory(() => {\n let indicator: PadroneProgress | undefined;\n let restoreOutput: (() => void) | undefined;\n // Lazily resolved from context + constructor args\n let resolvedRenderer: PadroneProgressRenderer | undefined;\n let resolvedOptions: PadroneProgressOptions | undefined;\n let resolvedSilent = false;\n let msgs: ReturnType<typeof resolveMessages> | undefined;\n\n function resolve(ctx: { context?: { progressConfig?: PadroneProgressDefaults } }) {\n if (resolvedRenderer) return;\n const ctxCfg = (ctx.context as Record<string, unknown> | undefined)?.progressConfig as PadroneProgressDefaults | undefined;\n resolvedSilent = rawSilent ?? ctxCfg?.silent ?? false;\n const spinner = rawSpinner ?? ctxCfg?.spinner;\n const bar = rawBar ?? ctxCfg?.bar;\n const time = rawTime ?? ctxCfg?.time;\n const eta = rawEta ?? ctxCfg?.eta;\n resolvedRenderer = rawRenderer ?? ctxCfg?.renderer ?? createTerminalProgress;\n resolvedOptions =\n spinner !== undefined || bar !== undefined || time !== undefined || eta !== undefined ? { spinner, bar, time, eta } : undefined;\n msgs = mergeMessages(resolveMessages(rawMessage), resolveMessages(ctxCfg?.message), rawMessage);\n }\n\n const teardown = () => {\n restoreOutput?.();\n indicator = undefined;\n restoreOutput = undefined;\n };\n\n return {\n validate(ctx, next) {\n resolve(ctx);\n if (resolvedSilent) return next();\n indicator = resolvedRenderer!(msgs!.validation || msgs!.progress, resolvedOptions);\n\n const originalOutput = ctx.runtime.output;\n const originalError = ctx.runtime.error;\n ctx.runtime.output = (...args: unknown[]) => {\n indicator!.pause();\n originalOutput(...args);\n indicator!.resume();\n };\n ctx.runtime.error = (text: string) => {\n indicator!.pause();\n originalError(text);\n indicator!.resume();\n };\n restoreOutput = () => {\n ctx.runtime.output = originalOutput;\n ctx.runtime.error = originalError;\n };\n\n const onValidationFailure = (error: unknown) => {\n if (indicator) {\n cleanup(indicator, msgs!.success, msgs!.error, error, undefined, true);\n teardown();\n }\n };\n\n const checkResult = (result: any) => {\n if (result.argsResult?.issues) onValidationFailure(new Error('Validation failed'));\n return result;\n };\n\n let result: any;\n try {\n result = next();\n } catch (err) {\n onValidationFailure(err);\n throw err;\n }\n if (result instanceof Promise) {\n return result.then(checkResult, (err: unknown) => {\n onValidationFailure(err);\n throw err;\n });\n }\n return checkResult(result);\n },\n\n execute(_ctx, next) {\n if (resolvedSilent) return next({ context: { progress: noopIndicator } });\n\n // Transition from validation message to progress message\n if (indicator && msgs!.validation) indicator.update(msgs!.progress);\n\n const effectiveIndicator = indicator ?? noopIndicator;\n\n const onSuccess = (value: unknown) => {\n cleanup(effectiveIndicator, msgs!.success, msgs!.error, undefined, value, false);\n teardown();\n };\n const onError = (err: unknown) => {\n if (indicator) {\n cleanup(indicator, msgs!.success, msgs!.error, err, undefined, true);\n teardown();\n }\n throw err;\n };\n\n let result: any;\n try {\n result = next({ context: { progress: effectiveIndicator } });\n } catch (err) {\n onError(err);\n }\n if (result instanceof Promise) {\n return result.then(\n (r) => {\n if (r.result instanceof Promise) {\n return {\n result: r.result.then(\n (value: unknown) => {\n onSuccess(value);\n return value;\n },\n (err: unknown) => onError(err),\n ),\n };\n }\n onSuccess(r.result);\n return r;\n },\n (err: unknown) => onError(err),\n );\n }\n if (result!.result instanceof Promise) {\n return {\n result: result!.result.then(\n (value: unknown) => {\n onSuccess(value);\n return value;\n },\n (err: unknown) => onError(err),\n ),\n };\n }\n onSuccess(result!.result);\n return result;\n },\n\n shutdown(ctx) {\n // Safety net: if validate/execute cleanup paths were bypassed (e.g., outer interceptor\n // threw during execute before reaching this interceptor's execute handler), stop the indicator.\n if (indicator) {\n cleanup(indicator, msgs!.success, msgs!.error, ctx.error, ctx.result, !!ctx.error);\n teardown();\n }\n },\n };\n })\n .provides<{ progress: PadroneProgress }>();\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\n\n/**\n * Extension that adds an auto-managed progress indicator to the command pipeline.\n *\n * - `string` — a single message used for all states.\n * - `PadroneProgressConfig` — separate messages for validation, progress, success, and error.\n *\n * The indicator is automatically started before validation, updated at each phase transition,\n * and stopped on success (`.succeed()`) or failure (`.fail()`).\n *\n * Provides `{ progress: PadroneProgress }` on the command context.\n * Access it in action handlers as `ctx.context.progress`.\n *\n * Uses the built-in terminal renderer by default. Pass a custom `renderer` for non-terminal\n * environments (web UIs, testing, etc).\n *\n * Usage:\n * ```ts\n * createPadrone('my-cli')\n * .command('sync', (c) =>\n * c.extend(padroneProgress('Syncing...'))\n * .action((_args, ctx) => {\n * ctx.context.progress.update('halfway');\n * })\n * )\n * ```\n */\nexport function padroneProgress<T extends CommandTypesBase>(config?: string | PadroneProgressConfig): (builder: T) => WithProgress<T> {\n return ((builder: AnyPadroneBuilder) => builder.intercept(progressInterceptor(config ?? 'Working...'))) as any;\n}\n"],"mappings":";;;AAkEA,MAAM,gBAAiC;CACrC,SAAS,CAAC;CACV,KAAK;EAHW,QAAQ,CAAC;EAAG,OAAO,CAAC;EAAG,QAAQ,CAAC;CAGrC;CACX,UAAU,CAAC;CACX,OAAO,CAAC;CACR,OAAO,CAAC;CACR,QAAQ,CAAC;CACT,SAAS,CAAC;AACZ;AAEA,SAAS,eAAe,OAAgB,OAAgB,UAA+E;CACrI,MAAM,MAAM,OAAO,UAAU,aAAc,MAAkC,KAAK,IAAI;CACtF,IAAI,QAAQ,KAAA,GAAW,OAAO,EAAE,SAAS,SAAS;CAClD,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU,OAAO,EAAE,SAAS,IAAI;CACnE,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;EAC3C,MAAM,MAAM;EACZ,OAAO;GAAE,SAAS,IAAI;GAAS,WAAW,IAAI;EAAU;CAC1D;CACA,OAAO,EAAE,SAAS,SAAS;AAC7B;AAEA,SAAS,QACP,WACA,eACA,aACA,OACA,QACA,SACA;CACA,IAAI,SAAS;EAEX,MAAM,EAAE,SAAS,UAAU,WAAW,cAAc,eAAe,aAAa,OAD/D,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACyB;EAC/F,UAAU,KAAK,UAAU,cAAc,KAAA,IAAY,EAAE,WAAW,UAAU,IAAI,KAAA,CAAS;CACzF,OAAO;EACL,MAAM,EAAE,SAAS,YAAY,WAAW,gBAAgB,eAAe,eAAe,MAAM;EAC5F,UAAU,QAAQ,YAAY,gBAAgB,KAAA,IAAY,EAAE,WAAW,YAAY,IAAI,KAAA,CAAS;CAClG;AACF;AAMA,SAAS,gBAAgB,KAKvB;CACA,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB,OAAO;EAAE,UAAU,OAAO;EAAc,YAAY;EAAI,SAAS,KAAA;EAAW,OAAO,KAAA;CAAU;CAE/F,OAAO;EACL,UAAU,IAAI,YAAY;EAC1B,YAAY,IAAI,cAAc;EAC9B,SAAS,IAAI;EACb,OAAO,IAAI;CACb;AACF;AAEA,SAAS,cACP,KACA,KACA,QACoC;CAEpC,IAAI,OAAO,WAAW,UAAU,OAAO;CAEvC,MAAM,MAAO,OAAO,WAAW,WAAW,SAAS,KAAA;CACnD,OAAO;EACL,UAAU,KAAK,aAAa,KAAA,IAAY,IAAI,WAAY,IAAI,YAAY,IAAI;EAC5E,YAAY,KAAK,eAAe,KAAA,IAAY,IAAI,aAAa,IAAI,cAAc,IAAI;EACnF,SAAS,KAAK,YAAY,KAAA,IAAY,IAAI,UAAW,IAAI,WAAW,IAAI;EACxE,OAAO,KAAK,UAAU,KAAA,IAAY,IAAI,QAAS,IAAI,SAAS,IAAI;CAClE;AACF;AAEA,SAAS,oBAAoB,QAAwC;CACnE,MAAM,QAAQ,OAAO,WAAW;CAChC,MAAM,aAAa,OAAO,WAAW,WAAW,SAAS,QAAQ,OAAO,UAAU,KAAA;CAElF,MAAM,aAAa,QAAQ,OAAO,UAAU,KAAA;CAC5C,MAAM,SAAS,QAAQ,OAAO,MAAM,KAAA;CACpC,MAAM,cAAc,QAAQ,OAAO,WAAW,KAAA;CAC9C,MAAM,UAAU,QAAQ,OAAO,OAAO,KAAA;CACtC,MAAM,SAAS,QAAQ,OAAO,MAAM,KAAA;CACpC,MAAM,YAAY,QAAQ,OAAO,SAAS,KAAA;CAE1C,OAAO,kBAAkB;EAAE,IAAI;EAAoB,MAAM;CAAmB,CAAC,CAAC,CAC3E,SAAuD,CAAC,CACxD,cAAc;EACb,IAAI;EACJ,IAAI;EAEJ,IAAI;EACJ,IAAI;EACJ,IAAI,iBAAiB;EACrB,IAAI;EAEJ,SAAS,QAAQ,KAAiE;GAChF,IAAI,kBAAkB;GACtB,MAAM,SAAU,IAAI,SAAiD;GACrE,iBAAiB,aAAa,QAAQ,UAAU;GAChD,MAAM,UAAU,cAAc,QAAQ;GACtC,MAAM,MAAM,UAAU,QAAQ;GAC9B,MAAM,OAAO,WAAW,QAAQ;GAChC,MAAM,MAAM,UAAU,QAAQ;GAC9B,mBAAmB,eAAe,QAAQ,YAAY;GACtD,kBACE,YAAY,KAAA,KAAa,QAAQ,KAAA,KAAa,SAAS,KAAA,KAAa,QAAQ,KAAA,IAAY;IAAE;IAAS;IAAK;IAAM;GAAI,IAAI,KAAA;GACxH,OAAO,cAAc,gBAAgB,UAAU,GAAG,gBAAgB,QAAQ,OAAO,GAAG,UAAU;EAChG;EAEA,MAAM,iBAAiB;GACrB,gBAAgB;GAChB,YAAY,KAAA;GACZ,gBAAgB,KAAA;EAClB;EAEA,OAAO;GACL,SAAS,KAAK,MAAM;IAClB,QAAQ,GAAG;IACX,IAAI,gBAAgB,OAAO,KAAK;IAChC,YAAY,iBAAkB,KAAM,cAAc,KAAM,UAAU,eAAe;IAEjF,MAAM,iBAAiB,IAAI,QAAQ;IACnC,MAAM,gBAAgB,IAAI,QAAQ;IAClC,IAAI,QAAQ,UAAU,GAAG,SAAoB;KAC3C,UAAW,MAAM;KACjB,eAAe,GAAG,IAAI;KACtB,UAAW,OAAO;IACpB;IACA,IAAI,QAAQ,SAAS,SAAiB;KACpC,UAAW,MAAM;KACjB,cAAc,IAAI;KAClB,UAAW,OAAO;IACpB;IACA,sBAAsB;KACpB,IAAI,QAAQ,SAAS;KACrB,IAAI,QAAQ,QAAQ;IACtB;IAEA,MAAM,uBAAuB,UAAmB;KAC9C,IAAI,WAAW;MACb,QAAQ,WAAW,KAAM,SAAS,KAAM,OAAO,OAAO,KAAA,GAAW,IAAI;MACrE,SAAS;KACX;IACF;IAEA,MAAM,eAAe,WAAgB;KACnC,IAAI,OAAO,YAAY,QAAQ,oCAAoB,IAAI,MAAM,mBAAmB,CAAC;KACjF,OAAO;IACT;IAEA,IAAI;IACJ,IAAI;KACF,SAAS,KAAK;IAChB,SAAS,KAAK;KACZ,oBAAoB,GAAG;KACvB,MAAM;IACR;IACA,IAAI,kBAAkB,SACpB,OAAO,OAAO,KAAK,cAAc,QAAiB;KAChD,oBAAoB,GAAG;KACvB,MAAM;IACR,CAAC;IAEH,OAAO,YAAY,MAAM;GAC3B;GAEA,QAAQ,MAAM,MAAM;IAClB,IAAI,gBAAgB,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,cAAc,EAAE,CAAC;IAGxE,IAAI,aAAa,KAAM,YAAY,UAAU,OAAO,KAAM,QAAQ;IAElE,MAAM,qBAAqB,aAAa;IAExC,MAAM,aAAa,UAAmB;KACpC,QAAQ,oBAAoB,KAAM,SAAS,KAAM,OAAO,KAAA,GAAW,OAAO,KAAK;KAC/E,SAAS;IACX;IACA,MAAM,WAAW,QAAiB;KAChC,IAAI,WAAW;MACb,QAAQ,WAAW,KAAM,SAAS,KAAM,OAAO,KAAK,KAAA,GAAW,IAAI;MACnE,SAAS;KACX;KACA,MAAM;IACR;IAEA,IAAI;IACJ,IAAI;KACF,SAAS,KAAK,EAAE,SAAS,EAAE,UAAU,mBAAmB,EAAE,CAAC;IAC7D,SAAS,KAAK;KACZ,QAAQ,GAAG;IACb;IACA,IAAI,kBAAkB,SACpB,OAAO,OAAO,MACX,MAAM;KACL,IAAI,EAAE,kBAAkB,SACtB,OAAO,EACL,QAAQ,EAAE,OAAO,MACd,UAAmB;MAClB,UAAU,KAAK;MACf,OAAO;KACT,IACC,QAAiB,QAAQ,GAAG,CAC/B,EACF;KAEF,UAAU,EAAE,MAAM;KAClB,OAAO;IACT,IACC,QAAiB,QAAQ,GAAG,CAC/B;IAEF,IAAI,OAAQ,kBAAkB,SAC5B,OAAO,EACL,QAAQ,OAAQ,OAAO,MACpB,UAAmB;KAClB,UAAU,KAAK;KACf,OAAO;IACT,IACC,QAAiB,QAAQ,GAAG,CAC/B,EACF;IAEF,UAAU,OAAQ,MAAM;IACxB,OAAO;GACT;GAEA,SAAS,KAAK;IAGZ,IAAI,WAAW;KACb,QAAQ,WAAW,KAAM,SAAS,KAAM,OAAO,IAAI,OAAO,IAAI,QAAQ,CAAC,CAAC,IAAI,KAAK;KACjF,SAAS;IACX;GACF;EACF;CACF,CAAC,CAAC,CACD,SAAwC;AAC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,gBAA4C,QAA0E;CACpI,SAAS,YAA+B,QAAQ,UAAU,oBAAoB,UAAU,YAAY,CAAC;AACvG"}
@@ -0,0 +1,26 @@
1
+ import { PadroneSchema } from "../types/schema.mjs";
2
+ import { WithCommand } from "../util/type-utils.mjs";
3
+ import { CommandTypesBase, PadroneCommand } from "../types/command.mjs";
4
+ import { PadroneReplPreferences } from "../types/preferences.mjs";
5
+ //#region src/extension/repl.d.ts
6
+ type ReplArgs = {
7
+ scope?: string;
8
+ };
9
+ type ReplCommand = PadroneCommand<'repl', '', PadroneSchema<ReplArgs>, void, [], [], true>;
10
+ type WithRepl<T> = WithCommand<T, 'repl', ReplCommand>;
11
+ /**
12
+ * Extension that adds REPL support:
13
+ * - `repl` command that starts an interactive REPL
14
+ * - `--repl` flag that starts the REPL from any invocation
15
+ *
16
+ * Usage:
17
+ * ```ts
18
+ * createPadrone('my-cli').extend(padroneRepl())
19
+ * ```
20
+ */
21
+ declare function padroneRepl(defaults?: PadroneReplPreferences & {
22
+ disabled?: boolean;
23
+ }): <T extends CommandTypesBase>(builder: T) => WithRepl<T>;
24
+ //#endregion
25
+ export { WithRepl, padroneRepl };
26
+ //# sourceMappingURL=repl.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl.d.mts","names":[],"sources":["../../src/extension/repl.ts"],"mappings":";;;;;KAiBK,QAAA;EAAa,KAAK;AAAA;AAAA,KAElB,WAAA,GAAc,cAAA,aAA2B,aAAA,CAAc,QAAA;AAAA,KAEhD,QAAA,MAAc,WAAA,CAAY,CAAA,UAAW,WAAA;;;;AAJ1B;AAAA;;;;;;iBAkBP,WAAA,CACd,QAAA,GAAW,sBAAA;EAA2B,QAAA;AAAA,eAC1B,gBAAA,EAAkB,OAAA,EAAS,CAAA,KAAM,QAAA,CAAS,CAAA"}
@@ -0,0 +1,67 @@
1
+ import { withDrain } from "../core/results.mjs";
2
+ import { defineInterceptor } from "../core/interceptors.mjs";
3
+ import { parseCliInputToParts } from "../core/parse.mjs";
4
+ import { passthroughSchema } from "./utils.mjs";
5
+ //#region src/extension/repl.ts
6
+ /**
7
+ * Extension that adds REPL support:
8
+ * - `repl` command that starts an interactive REPL
9
+ * - `--repl` flag that starts the REPL from any invocation
10
+ *
11
+ * Usage:
12
+ * ```ts
13
+ * createPadrone('my-cli').extend(padroneRepl())
14
+ * ```
15
+ */
16
+ function padroneRepl(defaults) {
17
+ const disabled = defaults?.disabled;
18
+ return ((builder) => builder.command("repl", (c) => c.configure({
19
+ description: "Start an interactive REPL",
20
+ hidden: true
21
+ }).arguments(passthroughSchema({ scope: "string" }), { positional: ["scope"] }).async().action(async (args, ctx) => {
22
+ const prefs = {
23
+ ...defaults,
24
+ scope: args.scope ?? defaults?.scope
25
+ };
26
+ const { value } = await ctx.program.repl(prefs).drain();
27
+ return value;
28
+ })).intercept(createReplInterceptor(defaults, disabled)));
29
+ }
30
+ function createReplInterceptor(defaults, disabled) {
31
+ return defineInterceptor({
32
+ id: "padrone:repl",
33
+ name: "padrone:repl",
34
+ order: -1e3,
35
+ disabled
36
+ }, () => ({ start(ctx, next) {
37
+ const replInfo = checkReplFlag(ctx.input, ctx.command);
38
+ if (!replInfo) return next();
39
+ const program = ctx.program;
40
+ if (!program?.repl) return next();
41
+ const prefs = {
42
+ ...defaults,
43
+ scope: replInfo.scope ?? defaults?.scope
44
+ };
45
+ return program.repl(prefs).drain().then((r) => withDrain({
46
+ command: ctx.command,
47
+ args: void 0,
48
+ result: r.value
49
+ }));
50
+ } }));
51
+ }
52
+ /** Check for --repl flag in input. */
53
+ function checkReplFlag(input, rootCommand) {
54
+ if (!input) return null;
55
+ const parts = parseCliInputToParts(input);
56
+ const terms = parts.filter((p) => p.type === "term").map((p) => p.value);
57
+ const args = parts.filter((p) => p.type === "named");
58
+ const keyIs = (key, name) => key.length === 1 && key[0] === name;
59
+ if (!args.some((p) => p.type === "named" && keyIs(p.key, "repl"))) return null;
60
+ const normalizedTerms = [...terms];
61
+ if (normalizedTerms[0] === rootCommand.name) normalizedTerms.shift();
62
+ return { scope: normalizedTerms.length > 0 ? normalizedTerms.join(" ") : void 0 };
63
+ }
64
+ //#endregion
65
+ export { padroneRepl };
66
+
67
+ //# sourceMappingURL=repl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl.mjs","names":[],"sources":["../../src/extension/repl.ts"],"sourcesContent":["import { defineInterceptor } from '../core/interceptors.ts';\nimport { parseCliInputToParts } from '../core/parse.ts';\nimport { withDrain } from '../core/results.ts';\nimport type {\n AnyPadroneBuilder,\n AnyPadroneCommand,\n CommandTypesBase,\n InterceptorStartContext,\n PadroneCommand,\n PadroneReplPreferences,\n} from '../types/index.ts';\nimport type { PadroneSchema } from '../types/schema.ts';\nimport type { WithCommand } from '../util/type-utils.ts';\nimport { passthroughSchema } from './utils.ts';\n\n// ── Types ────────────────────────────────────────────────────────────────\n\ntype ReplArgs = { scope?: string };\n\ntype ReplCommand = PadroneCommand<'repl', '', PadroneSchema<ReplArgs>, void, [], [], true>;\n\nexport type WithRepl<T> = WithCommand<T, 'repl', ReplCommand>;\n\n// ── Extension ────────────────────────────────────────────────────────────\n\n/**\n * Extension that adds REPL support:\n * - `repl` command that starts an interactive REPL\n * - `--repl` flag that starts the REPL from any invocation\n *\n * Usage:\n * ```ts\n * createPadrone('my-cli').extend(padroneRepl())\n * ```\n */\nexport function padroneRepl(\n defaults?: PadroneReplPreferences & { disabled?: boolean },\n): <T extends CommandTypesBase>(builder: T) => WithRepl<T> {\n const disabled = defaults?.disabled;\n return ((builder: AnyPadroneBuilder) =>\n builder\n .command('repl', (c) =>\n c\n .configure({ description: 'Start an interactive REPL', hidden: true })\n .arguments(passthroughSchema({ scope: 'string' }), { positional: ['scope'] })\n .async()\n .action(async (args, ctx) => {\n const prefs: PadroneReplPreferences = { ...defaults, scope: args.scope ?? defaults?.scope };\n const repl = ctx.program.repl(prefs);\n const { value } = await repl.drain();\n return value;\n }),\n )\n .intercept(createReplInterceptor(defaults, disabled))) as any;\n}\n\nfunction createReplInterceptor(defaults?: PadroneReplPreferences, disabled?: boolean) {\n return defineInterceptor({ id: 'padrone:repl', name: 'padrone:repl', order: -1000, disabled }, () => ({\n start(ctx: InterceptorStartContext, next: () => unknown) {\n const replInfo = checkReplFlag(ctx.input, ctx.command);\n if (!replInfo) return next();\n\n const program = ctx.program;\n if (!program?.repl) return next();\n\n const prefs: PadroneReplPreferences = { ...defaults, scope: replInfo.scope ?? defaults?.scope };\n\n // Return a Promise so the pipeline awaits the REPL result\n return program\n .repl(prefs)\n .drain()\n .then((r: any) => withDrain({ command: ctx.command, args: undefined, result: r.value }));\n },\n }));\n}\n\n/** Check for --repl flag in input. */\nfunction checkReplFlag(input: string | undefined, rootCommand: AnyPadroneCommand): { scope?: string } | null {\n if (!input) return null;\n\n const parts = parseCliInputToParts(input);\n const terms = parts.filter((p) => p.type === 'term').map((p) => p.value);\n const args = parts.filter((p) => p.type === 'named');\n const keyIs = (key: string[], name: string) => key.length === 1 && key[0] === name;\n\n const hasReplFlag = args.some((p) => p.type === 'named' && keyIs(p.key, 'repl'));\n if (!hasReplFlag) return null;\n\n const normalizedTerms = [...terms];\n if (normalizedTerms[0] === rootCommand.name) normalizedTerms.shift();\n\n const scope = normalizedTerms.length > 0 ? normalizedTerms.join(' ') : undefined;\n return { scope };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmCA,SAAgB,YACd,UACyD;CACzD,MAAM,WAAW,UAAU;CAC3B,SAAS,YACP,QACG,QAAQ,SAAS,MAChB,EACG,UAAU;EAAE,aAAa;EAA6B,QAAQ;CAAK,CAAC,CAAC,CACrE,UAAU,kBAAkB,EAAE,OAAO,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAC5E,MAAM,CAAC,CACP,OAAO,OAAO,MAAM,QAAQ;EAC3B,MAAM,QAAgC;GAAE,GAAG;GAAU,OAAO,KAAK,SAAS,UAAU;EAAM;EAE1F,MAAM,EAAE,UAAU,MADL,IAAI,QAAQ,KAAK,KACH,CAAC,CAAC,MAAM;EACnC,OAAO;CACT,CAAC,CACL,CAAC,CACA,UAAU,sBAAsB,UAAU,QAAQ,CAAC;AAC1D;AAEA,SAAS,sBAAsB,UAAmC,UAAoB;CACpF,OAAO,kBAAkB;EAAE,IAAI;EAAgB,MAAM;EAAgB,OAAO;EAAO;CAAS,UAAU,EACpG,MAAM,KAA8B,MAAqB;EACvD,MAAM,WAAW,cAAc,IAAI,OAAO,IAAI,OAAO;EACrD,IAAI,CAAC,UAAU,OAAO,KAAK;EAE3B,MAAM,UAAU,IAAI;EACpB,IAAI,CAAC,SAAS,MAAM,OAAO,KAAK;EAEhC,MAAM,QAAgC;GAAE,GAAG;GAAU,OAAO,SAAS,SAAS,UAAU;EAAM;EAG9F,OAAO,QACJ,KAAK,KAAK,CAAC,CACX,MAAM,CAAC,CACP,MAAM,MAAW,UAAU;GAAE,SAAS,IAAI;GAAS,MAAM,KAAA;GAAW,QAAQ,EAAE;EAAM,CAAC,CAAC;CAC3F,EACF,EAAE;AACJ;;AAGA,SAAS,cAAc,OAA2B,aAA2D;CAC3G,IAAI,CAAC,OAAO,OAAO;CAEnB,MAAM,QAAQ,qBAAqB,KAAK;CACxC,MAAM,QAAQ,MAAM,QAAQ,MAAM,EAAE,SAAS,MAAM,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK;CACvE,MAAM,OAAO,MAAM,QAAQ,MAAM,EAAE,SAAS,OAAO;CACnD,MAAM,SAAS,KAAe,SAAiB,IAAI,WAAW,KAAK,IAAI,OAAO;CAG9E,IAAI,CADgB,KAAK,MAAM,MAAM,EAAE,SAAS,WAAW,MAAM,EAAE,KAAK,MAAM,CAC/D,GAAG,OAAO;CAEzB,MAAM,kBAAkB,CAAC,GAAG,KAAK;CACjC,IAAI,gBAAgB,OAAO,YAAY,MAAM,gBAAgB,MAAM;CAGnE,OAAO,EAAE,OADK,gBAAgB,SAAS,IAAI,gBAAgB,KAAK,GAAG,IAAI,KAAA,EACxD;AACjB"}
@@ -0,0 +1,27 @@
1
+ import { PadroneSchema } from "../types/schema.mjs";
2
+ import { WithCommand } from "../util/type-utils.mjs";
3
+ import { PadroneServePreferences } from "../feature/serve.mjs";
4
+ import { CommandTypesBase, PadroneCommand } from "../types/command.mjs";
5
+ //#region src/extension/serve.d.ts
6
+ type ServeArgs = {
7
+ port?: string;
8
+ host?: string;
9
+ basePath?: string;
10
+ };
11
+ type ServeCommand = PadroneCommand<'serve', '', PadroneSchema<ServeArgs>, void, [], [], true>;
12
+ type WithServe<T> = WithCommand<T, 'serve', ServeCommand>;
13
+ /**
14
+ * Extension that adds the `serve` command for starting a REST HTTP server.
15
+ *
16
+ * Usage:
17
+ * ```ts
18
+ * import { createPadrone } from 'padrone';
19
+ * import { padroneServe } from 'padrone/serve';
20
+ *
21
+ * createPadrone('my-cli').extend(padroneServe())
22
+ * ```
23
+ */
24
+ declare function padroneServe(defaults?: PadroneServePreferences): <T extends CommandTypesBase>(builder: T) => WithServe<T>;
25
+ //#endregion
26
+ export { WithServe, padroneServe };
27
+ //# sourceMappingURL=serve.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.mts","names":[],"sources":["../../src/extension/serve.ts"],"mappings":";;;;;KAUK,SAAA;EAAc,IAAA;EAAe,IAAA;EAAe,QAAA;AAAA;AAAA,KAE5C,YAAA,GAAe,cAAA,cAA4B,aAAA,CAAc,SAAA;AAAA,KAElD,SAAA,MAAe,WAAA,CAAY,CAAA,WAAY,YAAA;;;;;AAJM;AAAA;;;;;;iBAmBzC,YAAA,CAAa,QAAA,GAAW,uBAAA,cAAqC,gBAAA,EAAkB,OAAA,EAAS,CAAA,KAAM,SAAA,CAAU,CAAA"}
@@ -0,0 +1,41 @@
1
+ import { resolveAllCommands } from "../core/commands.mjs";
2
+ import { getRootCommand } from "../util/utils.mjs";
3
+ import { passthroughSchema } from "./utils.mjs";
4
+ //#region src/extension/serve.ts
5
+ /**
6
+ * Extension that adds the `serve` command for starting a REST HTTP server.
7
+ *
8
+ * Usage:
9
+ * ```ts
10
+ * import { createPadrone } from 'padrone';
11
+ * import { padroneServe } from 'padrone/serve';
12
+ *
13
+ * createPadrone('my-cli').extend(padroneServe())
14
+ * ```
15
+ */
16
+ function padroneServe(defaults) {
17
+ return ((builder) => builder.command("serve", (c) => c.configure({
18
+ description: "Start a REST HTTP server",
19
+ hidden: true
20
+ }).arguments(passthroughSchema({
21
+ port: "string",
22
+ host: "string",
23
+ "base-path": "string"
24
+ })).async().action(async (args, ctx) => {
25
+ const rootCommand = getRootCommand(ctx.command);
26
+ resolveAllCommands(rootCommand);
27
+ const { startServeServer } = await import("../feature/serve.mjs");
28
+ const port = args.port ? parseInt(args.port, 10) : void 0;
29
+ const prefs = {
30
+ ...defaults,
31
+ port: port && !Number.isNaN(port) ? port : defaults?.port,
32
+ host: args.host ?? defaults?.host,
33
+ basePath: args["base-path"] ?? defaults?.basePath
34
+ };
35
+ await startServeServer(ctx.program, rootCommand, ctx.program.eval, prefs);
36
+ })));
37
+ }
38
+ //#endregion
39
+ export { padroneServe };
40
+
41
+ //# sourceMappingURL=serve.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.mjs","names":[],"sources":["../../src/extension/serve.ts"],"sourcesContent":["import { resolveAllCommands } from '../core/commands.ts';\nimport type { PadroneServePreferences } from '../feature/serve.ts';\nimport type { AnyPadroneBuilder, CommandTypesBase, PadroneCommand } from '../types/index.ts';\nimport type { PadroneSchema } from '../types/schema.ts';\nimport type { WithCommand } from '../util/type-utils.ts';\nimport { getRootCommand } from '../util/utils.ts';\nimport { passthroughSchema } from './utils.ts';\n\n// ── Types ────────────────────────────────────────────────────────────────\n\ntype ServeArgs = { port?: string; host?: string; basePath?: string };\n\ntype ServeCommand = PadroneCommand<'serve', '', PadroneSchema<ServeArgs>, void, [], [], true>;\n\nexport type WithServe<T> = WithCommand<T, 'serve', ServeCommand>;\n\n// ── Extension ────────────────────────────────────────────────────────────\n\n/**\n * Extension that adds the `serve` command for starting a REST HTTP server.\n *\n * Usage:\n * ```ts\n * import { createPadrone } from 'padrone';\n * import { padroneServe } from 'padrone/serve';\n *\n * createPadrone('my-cli').extend(padroneServe())\n * ```\n */\nexport function padroneServe(defaults?: PadroneServePreferences): <T extends CommandTypesBase>(builder: T) => WithServe<T> {\n return ((builder: AnyPadroneBuilder) =>\n builder.command('serve', (c) =>\n c\n .configure({ description: 'Start a REST HTTP server', hidden: true })\n .arguments(passthroughSchema({ port: 'string', host: 'string', 'base-path': 'string' }))\n .async()\n .action(async (args, ctx) => {\n const rootCommand = getRootCommand(ctx.command);\n resolveAllCommands(rootCommand);\n const { startServeServer } = await import('../feature/serve.ts');\n const port = args.port ? parseInt(args.port, 10) : undefined;\n const prefs: PadroneServePreferences = {\n ...defaults,\n port: port && !Number.isNaN(port) ? port : defaults?.port,\n host: args.host ?? defaults?.host,\n basePath: args['base-path'] ?? defaults?.basePath,\n };\n await startServeServer(ctx.program, rootCommand, ctx.program.eval, prefs);\n }),\n )) as any;\n}\n"],"mappings":";;;;;;;;;;;;;;;AA6BA,SAAgB,aAAa,UAA8F;CACzH,SAAS,YACP,QAAQ,QAAQ,UAAU,MACxB,EACG,UAAU;EAAE,aAAa;EAA4B,QAAQ;CAAK,CAAC,CAAC,CACpE,UAAU,kBAAkB;EAAE,MAAM;EAAU,MAAM;EAAU,aAAa;CAAS,CAAC,CAAC,CAAC,CACvF,MAAM,CAAC,CACP,OAAO,OAAO,MAAM,QAAQ;EAC3B,MAAM,cAAc,eAAe,IAAI,OAAO;EAC9C,mBAAmB,WAAW;EAC9B,MAAM,EAAE,qBAAqB,MAAM,OAAO;EAC1C,MAAM,OAAO,KAAK,OAAO,SAAS,KAAK,MAAM,EAAE,IAAI,KAAA;EACnD,MAAM,QAAiC;GACrC,GAAG;GACH,MAAM,QAAQ,CAAC,OAAO,MAAM,IAAI,IAAI,OAAO,UAAU;GACrD,MAAM,KAAK,QAAQ,UAAU;GAC7B,UAAU,KAAK,gBAAgB,UAAU;EAC3C;EACA,MAAM,iBAAiB,IAAI,SAAS,aAAa,IAAI,QAAQ,MAAM,KAAK;CAC1E,CAAC,CACL;AACJ"}
@@ -0,0 +1,19 @@
1
+ import { CommandTypesBase } from "../types/command.mjs";
2
+ //#region src/extension/signal.d.ts
3
+ /**
4
+ * Extension that wires process signal handling (SIGINT, SIGTERM, SIGHUP) into the interceptor lifecycle.
5
+ *
6
+ * - Creates an `AbortController` whose signal is propagated to all downstream phases.
7
+ * - Subscribes to `runtime.onSignal` to forward OS signals to the abort controller.
8
+ * - Implements SIGINT double-tap: two SIGINTs within 2 seconds force-exits the process.
9
+ * - Attaches `signal` and `exitCode` to results and errors when interrupted.
10
+ * - Cleans up the signal subscription on completion or failure.
11
+ *
12
+ * Included in the default extensions. Runs at order `-2000` (outermost).
13
+ */
14
+ declare function padroneSignalHandling(options?: {
15
+ disabled?: boolean;
16
+ }): <T extends CommandTypesBase>(builder: T) => T;
17
+ //#endregion
18
+ export { padroneSignalHandling };
19
+ //# sourceMappingURL=signal.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal.d.mts","names":[],"sources":["../../src/extension/signal.ts"],"mappings":";;;;;AAmFA;;;;;;;;iBAAgB,qBAAA,CAAsB,OAAA;EAAY,QAAA;AAAA,eAAkC,gBAAA,EAAkB,OAAA,EAAS,CAAA,KAAM,CAAA"}
@@ -0,0 +1,81 @@
1
+ import { thenMaybe } from "../core/results.mjs";
2
+ import { defineInterceptor } from "../core/interceptors.mjs";
3
+ import { SignalError, signalExitCode } from "../core/errors.mjs";
4
+ //#region src/extension/signal.ts
5
+ const signalMeta = {
6
+ id: "padrone:signal",
7
+ name: "padrone:signal",
8
+ order: -2e3
9
+ };
10
+ const signalInterceptor = defineInterceptor(signalMeta, () => {
11
+ const abortController = new AbortController();
12
+ let receivedSignal;
13
+ let lastSigintTime = 0;
14
+ let unsubscribe;
15
+ const DOUBLE_SIGINT_MS = 2e3;
16
+ const cleanup = () => {
17
+ unsubscribe?.();
18
+ unsubscribe = void 0;
19
+ };
20
+ const attachSignalInfo = (result) => {
21
+ if (receivedSignal && result && typeof result === "object") {
22
+ result.signal = receivedSignal;
23
+ result.exitCode = signalExitCode(receivedSignal);
24
+ }
25
+ return result;
26
+ };
27
+ return {
28
+ start(ctx, next) {
29
+ const runtimeExit = ctx.runtime.exit;
30
+ unsubscribe = ctx.runtime.onSignal?.((sig) => {
31
+ if (abortController.signal.aborted) {
32
+ if (sig === "SIGINT") {
33
+ const elapsed = Date.now() - lastSigintTime;
34
+ if (elapsed > 0 && elapsed < DOUBLE_SIGINT_MS) runtimeExit?.(signalExitCode(sig));
35
+ lastSigintTime = Date.now();
36
+ }
37
+ return;
38
+ }
39
+ if (sig === "SIGINT") lastSigintTime = Date.now();
40
+ receivedSignal = sig;
41
+ abortController.abort(sig);
42
+ });
43
+ return thenMaybe(next({ signal: abortController.signal }), (r) => {
44
+ cleanup();
45
+ return attachSignalInfo(r);
46
+ });
47
+ },
48
+ error(_ctx, next) {
49
+ return thenMaybe(next(), (er) => {
50
+ if (receivedSignal && er.error instanceof Error) er.error = new SignalError(receivedSignal, { cause: er.error });
51
+ return er;
52
+ });
53
+ },
54
+ shutdown(_ctx, next) {
55
+ cleanup();
56
+ return next();
57
+ }
58
+ };
59
+ });
60
+ /**
61
+ * Extension that wires process signal handling (SIGINT, SIGTERM, SIGHUP) into the interceptor lifecycle.
62
+ *
63
+ * - Creates an `AbortController` whose signal is propagated to all downstream phases.
64
+ * - Subscribes to `runtime.onSignal` to forward OS signals to the abort controller.
65
+ * - Implements SIGINT double-tap: two SIGINTs within 2 seconds force-exits the process.
66
+ * - Attaches `signal` and `exitCode` to results and errors when interrupted.
67
+ * - Cleans up the signal subscription on completion or failure.
68
+ *
69
+ * Included in the default extensions. Runs at order `-2000` (outermost).
70
+ */
71
+ function padroneSignalHandling(options) {
72
+ const interceptor = options?.disabled ? defineInterceptor({
73
+ ...signalMeta,
74
+ disabled: true
75
+ }, () => ({})) : signalInterceptor;
76
+ return ((builder) => builder.intercept(interceptor));
77
+ }
78
+ //#endregion
79
+ export { padroneSignalHandling };
80
+
81
+ //# sourceMappingURL=signal.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal.mjs","names":[],"sources":["../../src/extension/signal.ts"],"sourcesContent":["import { SignalError, signalExitCode } from '../core/errors.ts';\nimport { defineInterceptor } from '../core/interceptors.ts';\nimport { thenMaybe } from '../core/results.ts';\nimport type { PadroneSignal } from '../core/runtime.ts';\nimport type { AnyPadroneBuilder, CommandTypesBase } from '../types/index.ts';\n\n// ── Interceptor ─────────────────────────────────────────────────────────\n\nconst signalMeta = { id: 'padrone:signal', name: 'padrone:signal', order: -2000 } as const;\n\nconst signalInterceptor = defineInterceptor(signalMeta, () => {\n const abortController = new AbortController();\n let receivedSignal: PadroneSignal | undefined;\n let lastSigintTime = 0;\n let unsubscribe: (() => void) | undefined;\n const DOUBLE_SIGINT_MS = 2000;\n\n const cleanup = () => {\n unsubscribe?.();\n unsubscribe = undefined;\n };\n\n const attachSignalInfo = <T>(result: T): T => {\n if (receivedSignal && result && typeof result === 'object') {\n (result as any).signal = receivedSignal;\n (result as any).exitCode = signalExitCode(receivedSignal);\n }\n return result;\n };\n\n return {\n start(ctx, next) {\n const runtimeExit = ctx.runtime.exit;\n unsubscribe = ctx.runtime.onSignal?.((sig) => {\n if (abortController.signal.aborted) {\n if (sig === 'SIGINT') {\n const elapsed = Date.now() - lastSigintTime;\n if (elapsed > 0 && elapsed < DOUBLE_SIGINT_MS) {\n runtimeExit?.(signalExitCode(sig));\n }\n lastSigintTime = Date.now();\n }\n return;\n }\n if (sig === 'SIGINT') lastSigintTime = Date.now();\n receivedSignal = sig;\n abortController.abort(sig);\n });\n\n const result = next({ signal: abortController.signal });\n return thenMaybe(result, (r) => {\n cleanup();\n return attachSignalInfo(r);\n });\n },\n error(_ctx, next) {\n return thenMaybe(next(), (er) => {\n if (receivedSignal && er.error instanceof Error) {\n er.error = new SignalError(receivedSignal, { cause: er.error });\n }\n return er;\n });\n },\n shutdown(_ctx, next) {\n cleanup();\n return next();\n },\n };\n});\n\n// ── Extension ───────────────────────────────────────────────────────────\n\n/**\n * Extension that wires process signal handling (SIGINT, SIGTERM, SIGHUP) into the interceptor lifecycle.\n *\n * - Creates an `AbortController` whose signal is propagated to all downstream phases.\n * - Subscribes to `runtime.onSignal` to forward OS signals to the abort controller.\n * - Implements SIGINT double-tap: two SIGINTs within 2 seconds force-exits the process.\n * - Attaches `signal` and `exitCode` to results and errors when interrupted.\n * - Cleans up the signal subscription on completion or failure.\n *\n * Included in the default extensions. Runs at order `-2000` (outermost).\n */\nexport function padroneSignalHandling(options?: { disabled?: boolean }): <T extends CommandTypesBase>(builder: T) => T {\n const interceptor = options?.disabled ? defineInterceptor({ ...signalMeta, disabled: true }, () => ({})) : signalInterceptor;\n return ((builder: AnyPadroneBuilder) => builder.intercept(interceptor)) as any;\n}\n"],"mappings":";;;;AAQA,MAAM,aAAa;CAAE,IAAI;CAAkB,MAAM;CAAkB,OAAO;AAAM;AAEhF,MAAM,oBAAoB,kBAAkB,kBAAkB;CAC5D,MAAM,kBAAkB,IAAI,gBAAgB;CAC5C,IAAI;CACJ,IAAI,iBAAiB;CACrB,IAAI;CACJ,MAAM,mBAAmB;CAEzB,MAAM,gBAAgB;EACpB,cAAc;EACd,cAAc,KAAA;CAChB;CAEA,MAAM,oBAAuB,WAAiB;EAC5C,IAAI,kBAAkB,UAAU,OAAO,WAAW,UAAU;GAC1D,OAAgB,SAAS;GACzB,OAAgB,WAAW,eAAe,cAAc;EAC1D;EACA,OAAO;CACT;CAEA,OAAO;EACL,MAAM,KAAK,MAAM;GACf,MAAM,cAAc,IAAI,QAAQ;GAChC,cAAc,IAAI,QAAQ,YAAY,QAAQ;IAC5C,IAAI,gBAAgB,OAAO,SAAS;KAClC,IAAI,QAAQ,UAAU;MACpB,MAAM,UAAU,KAAK,IAAI,IAAI;MAC7B,IAAI,UAAU,KAAK,UAAU,kBAC3B,cAAc,eAAe,GAAG,CAAC;MAEnC,iBAAiB,KAAK,IAAI;KAC5B;KACA;IACF;IACA,IAAI,QAAQ,UAAU,iBAAiB,KAAK,IAAI;IAChD,iBAAiB;IACjB,gBAAgB,MAAM,GAAG;GAC3B,CAAC;GAGD,OAAO,UADQ,KAAK,EAAE,QAAQ,gBAAgB,OAAO,CAC/B,IAAI,MAAM;IAC9B,QAAQ;IACR,OAAO,iBAAiB,CAAC;GAC3B,CAAC;EACH;EACA,MAAM,MAAM,MAAM;GAChB,OAAO,UAAU,KAAK,IAAI,OAAO;IAC/B,IAAI,kBAAkB,GAAG,iBAAiB,OACxC,GAAG,QAAQ,IAAI,YAAY,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAAC;IAEhE,OAAO;GACT,CAAC;EACH;EACA,SAAS,MAAM,MAAM;GACnB,QAAQ;GACR,OAAO,KAAK;EACd;CACF;AACF,CAAC;;;;;;;;;;;;AAeD,SAAgB,sBAAsB,SAAiF;CACrH,MAAM,cAAc,SAAS,WAAW,kBAAkB;EAAE,GAAG;EAAY,UAAU;CAAK,UAAU,CAAC,EAAE,IAAI;CAC3G,SAAS,YAA+B,QAAQ,UAAU,WAAW;AACvE"}
@@ -0,0 +1,19 @@
1
+ import { CommandTypesBase } from "../types/command.mjs";
2
+ //#region src/extension/stdin.d.ts
3
+ /**
4
+ * Extension that reads stdin data into the argument field specified by `meta.stdin`.
5
+ * Included by default via `createPadrone()`.
6
+ *
7
+ * Read mode is inferred from the schema type:
8
+ * - `string` field → reads all stdin as a single string
9
+ * - `string[]` field → reads stdin line-by-line into an array
10
+ * - `AsyncIterable` field → returns a stream for line-by-line async consumption
11
+ *
12
+ * Stdin is only read when piped (not a TTY) and the field wasn't already provided via CLI flags.
13
+ */
14
+ declare function padroneStdin(options?: {
15
+ disabled?: boolean;
16
+ }): <T extends CommandTypesBase>(builder: T) => T;
17
+ //#endregion
18
+ export { padroneStdin };
19
+ //# sourceMappingURL=stdin.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin.d.mts","names":[],"sources":["../../src/extension/stdin.ts"],"mappings":";;;;;AA0DA;;;;;;;;iBAAgB,YAAA,CAAa,OAAA;EAAY,QAAA;AAAA,eAAkC,gBAAA,EAAkB,OAAA,EAAS,CAAA,KAAM,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { createStdinStream } from "../util/stream.mjs";
2
+ import { applyValues, isArrayField, isAsyncStreamField } from "../core/args.mjs";
3
+ import { resolveStdin, resolveStdinAlways } from "../core/default-runtime.mjs";
4
+ import { defineInterceptor } from "../core/interceptors.mjs";
5
+ //#region src/extension/stdin.ts
6
+ const stdinInterceptor = defineInterceptor({
7
+ id: "padrone:stdin",
8
+ name: "padrone:stdin",
9
+ order: -1001
10
+ }, () => ({ validate(ctx, next) {
11
+ const stdinField = ctx.command.meta?.stdin;
12
+ if (!stdinField) return next();
13
+ if (stdinField in ctx.rawArgs && ctx.rawArgs[stdinField] !== void 0) return next();
14
+ const streamInfo = isAsyncStreamField(ctx.command.argsSchema, stdinField);
15
+ if (streamInfo) {
16
+ const stdinForStream = resolveStdinAlways(ctx.runtime);
17
+ return next({ rawArgs: applyValues(ctx.rawArgs, { [stdinField]: createStdinStream(stdinForStream, streamInfo.itemSchema) }) });
18
+ }
19
+ const stdin = resolveStdin(ctx.runtime);
20
+ if (!stdin) return next();
21
+ if (isArrayField(ctx.command.argsSchema, stdinField)) return (async () => {
22
+ const lines = [];
23
+ for await (const line of stdin.lines()) lines.push(line);
24
+ return next({ rawArgs: applyValues(ctx.rawArgs, { [stdinField]: lines }) });
25
+ })();
26
+ return stdin.text().then((text) => {
27
+ if (!text) return next();
28
+ return next({ rawArgs: applyValues(ctx.rawArgs, { [stdinField]: text }) });
29
+ });
30
+ } }));
31
+ /**
32
+ * Extension that reads stdin data into the argument field specified by `meta.stdin`.
33
+ * Included by default via `createPadrone()`.
34
+ *
35
+ * Read mode is inferred from the schema type:
36
+ * - `string` field → reads all stdin as a single string
37
+ * - `string[]` field → reads stdin line-by-line into an array
38
+ * - `AsyncIterable` field → returns a stream for line-by-line async consumption
39
+ *
40
+ * Stdin is only read when piped (not a TTY) and the field wasn't already provided via CLI flags.
41
+ */
42
+ function padroneStdin(options) {
43
+ const interceptor = options?.disabled ? defineInterceptor({
44
+ ...stdinInterceptor,
45
+ disabled: true
46
+ }, () => ({})) : stdinInterceptor;
47
+ return ((builder) => builder.intercept(interceptor));
48
+ }
49
+ //#endregion
50
+ export { padroneStdin };
51
+
52
+ //# sourceMappingURL=stdin.mjs.map