specli 0.0.11 → 0.0.13

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 (335) hide show
  1. package/README.md +216 -325
  2. package/bin/cli.sh +27 -0
  3. package/dist/{src/ai → ai}/tools.d.ts +0 -1
  4. package/dist/ai/tools.js +161 -0
  5. package/dist/ai/tools.test.d.ts +1 -0
  6. package/dist/ai/tools.test.js +56 -0
  7. package/dist/{src/cli → cli}/auth-requirements.d.ts +0 -1
  8. package/dist/cli/auth-requirements.js +65 -0
  9. package/dist/cli/auth-requirements.test.d.ts +1 -0
  10. package/dist/cli/auth-requirements.test.js +16 -0
  11. package/dist/{src/cli → cli}/auth-schemes.d.ts +0 -1
  12. package/dist/cli/auth-schemes.js +112 -0
  13. package/dist/cli/auth-schemes.test.d.ts +1 -0
  14. package/dist/cli/auth-schemes.test.js +56 -0
  15. package/dist/{src/cli → cli}/capabilities.d.ts +0 -1
  16. package/dist/cli/capabilities.js +41 -0
  17. package/dist/cli/capabilities.test.d.ts +1 -0
  18. package/dist/cli/capabilities.test.js +84 -0
  19. package/dist/{src/cli → cli}/command-id.d.ts +0 -1
  20. package/dist/cli/command-id.js +8 -0
  21. package/dist/cli/command-id.test.d.ts +1 -0
  22. package/dist/cli/command-id.test.js +27 -0
  23. package/dist/{src/cli → cli}/command-index.d.ts +0 -1
  24. package/dist/cli/command-index.js +9 -0
  25. package/dist/{src/cli → cli}/command-model.d.ts +0 -1
  26. package/dist/cli/command-model.js +53 -0
  27. package/dist/cli/command-model.test.d.ts +1 -0
  28. package/dist/cli/command-model.test.js +40 -0
  29. package/dist/{src/cli → cli}/compile.d.ts +0 -1
  30. package/dist/cli/compile.js +79 -0
  31. package/dist/{src/cli → cli}/crypto.d.ts +0 -1
  32. package/dist/cli/crypto.js +9 -0
  33. package/dist/{src/cli → cli}/derive-name.d.ts +0 -1
  34. package/dist/cli/derive-name.js +96 -0
  35. package/dist/{src/cli → cli}/exec.d.ts +0 -1
  36. package/dist/cli/exec.js +50 -0
  37. package/dist/{src/cli → cli}/main.d.ts +0 -1
  38. package/dist/cli/main.js +177 -0
  39. package/dist/{src/cli → cli}/naming.d.ts +0 -1
  40. package/dist/cli/naming.js +191 -0
  41. package/dist/cli/naming.test.d.ts +1 -0
  42. package/dist/cli/naming.test.js +75 -0
  43. package/dist/{src/cli → cli}/operations.d.ts +0 -1
  44. package/dist/cli/operations.js +100 -0
  45. package/dist/cli/operations.test.d.ts +1 -0
  46. package/dist/cli/operations.test.js +51 -0
  47. package/dist/{src/cli → cli}/params.d.ts +0 -1
  48. package/dist/cli/params.js +36 -0
  49. package/dist/cli/params.test.d.ts +1 -0
  50. package/dist/cli/params.test.js +62 -0
  51. package/dist/{src/cli → cli}/pluralize.d.ts +0 -1
  52. package/dist/cli/pluralize.js +38 -0
  53. package/dist/{src/cli → cli}/positional.d.ts +0 -1
  54. package/dist/cli/positional.js +35 -0
  55. package/dist/cli/positional.test.d.ts +1 -0
  56. package/dist/cli/positional.test.js +60 -0
  57. package/dist/{src/cli → cli}/request-body.d.ts +0 -1
  58. package/dist/cli/request-body.js +44 -0
  59. package/dist/cli/request-body.test.d.ts +1 -0
  60. package/dist/cli/request-body.test.js +31 -0
  61. package/dist/{src/cli → cli}/runtime/argv.d.ts +0 -1
  62. package/dist/cli/runtime/argv.js +15 -0
  63. package/dist/{src/cli → cli}/runtime/auth/resolve.d.ts +0 -1
  64. package/dist/cli/runtime/auth/resolve.js +39 -0
  65. package/dist/{src/cli → cli}/runtime/body-flags.d.ts +0 -1
  66. package/dist/cli/runtime/body-flags.js +117 -0
  67. package/dist/cli/runtime/body-flags.test.d.ts +1 -0
  68. package/dist/cli/runtime/body-flags.test.js +192 -0
  69. package/dist/{src/cli → cli}/runtime/body.d.ts +0 -1
  70. package/dist/cli/runtime/body.js +16 -0
  71. package/dist/{src/cli → cli}/runtime/collect.d.ts +0 -1
  72. package/dist/cli/runtime/collect.js +3 -0
  73. package/dist/{src/cli → cli}/runtime/compat.d.ts +0 -1
  74. package/dist/cli/runtime/compat.js +78 -0
  75. package/dist/{src/cli → cli}/runtime/context.d.ts +0 -1
  76. package/dist/cli/runtime/context.js +44 -0
  77. package/dist/{src/cli → cli}/runtime/execute.d.ts +0 -1
  78. package/dist/cli/runtime/execute.js +106 -0
  79. package/dist/{src/cli → cli}/runtime/generated.d.ts +0 -1
  80. package/dist/cli/runtime/generated.js +168 -0
  81. package/dist/{src/cli → cli}/runtime/headers.d.ts +0 -1
  82. package/dist/cli/runtime/headers.js +30 -0
  83. package/dist/{src/cli → cli}/runtime/index.d.ts +0 -1
  84. package/dist/cli/runtime/index.js +3 -0
  85. package/dist/{src/cli → cli}/runtime/profile/secrets.d.ts +0 -1
  86. package/dist/cli/runtime/profile/secrets.js +53 -0
  87. package/dist/{src/cli → cli}/runtime/profile/store.d.ts +0 -1
  88. package/dist/cli/runtime/profile/store.js +63 -0
  89. package/dist/{src/cli → cli}/runtime/request.d.ts +0 -1
  90. package/dist/cli/runtime/request.js +283 -0
  91. package/dist/cli/runtime/request.test.d.ts +1 -0
  92. package/dist/cli/runtime/request.test.js +332 -0
  93. package/dist/{src/cli → cli}/runtime/server-url.d.ts +0 -1
  94. package/dist/cli/runtime/server-url.js +28 -0
  95. package/dist/{src/cli → cli}/runtime/template.d.ts +0 -1
  96. package/dist/cli/runtime/template.js +22 -0
  97. package/dist/cli/runtime/validate/ajv.d.ts +2 -0
  98. package/dist/cli/runtime/validate/ajv.js +11 -0
  99. package/dist/{src/cli → cli}/runtime/validate/coerce.d.ts +0 -1
  100. package/dist/cli/runtime/validate/coerce.js +63 -0
  101. package/dist/cli/runtime/validate/coerce.test.d.ts +1 -0
  102. package/dist/cli/runtime/validate/coerce.test.js +75 -0
  103. package/dist/{src/cli → cli}/runtime/validate/error.d.ts +0 -1
  104. package/dist/cli/runtime/validate/error.js +19 -0
  105. package/dist/{src/cli → cli}/runtime/validate/index.d.ts +0 -1
  106. package/dist/cli/runtime/validate/index.js +4 -0
  107. package/dist/{src/cli → cli}/runtime/validate/schema.d.ts +0 -1
  108. package/dist/cli/runtime/validate/schema.js +38 -0
  109. package/dist/{src/cli → cli}/schema-shape.d.ts +0 -1
  110. package/dist/cli/schema-shape.js +34 -0
  111. package/dist/{src/cli → cli}/schema.d.ts +0 -1
  112. package/dist/cli/schema.js +31 -0
  113. package/dist/{src/cli → cli}/server.d.ts +0 -1
  114. package/dist/cli/server.js +130 -0
  115. package/dist/cli/server.test.d.ts +1 -0
  116. package/dist/cli/server.test.js +49 -0
  117. package/dist/{src/cli → cli}/spec-id.d.ts +0 -1
  118. package/dist/cli/spec-id.js +8 -0
  119. package/dist/{src/cli → cli}/spec-loader.d.ts +0 -1
  120. package/dist/cli/spec-loader.js +40 -0
  121. package/dist/{src/cli → cli}/stable-json.d.ts +0 -1
  122. package/dist/cli/stable-json.js +29 -0
  123. package/dist/{src/cli → cli}/strings.d.ts +0 -1
  124. package/dist/cli/strings.js +20 -0
  125. package/dist/{src/cli → cli}/types.d.ts +0 -1
  126. package/dist/cli/types.js +3 -0
  127. package/dist/cli.d.ts +0 -1
  128. package/dist/cli.js +51 -2324
  129. package/dist/compiled.d.ts +2 -0
  130. package/{src/compiled.ts → dist/compiled.js} +8 -11
  131. package/dist/macros/env.d.ts +10 -0
  132. package/dist/macros/env.js +22 -0
  133. package/dist/macros/spec.d.ts +5 -0
  134. package/dist/macros/spec.js +16 -0
  135. package/package.json +17 -25
  136. package/bin/specli.js +0 -26
  137. package/cli.ts +0 -77
  138. package/dist/cli.d.ts.map +0 -1
  139. package/dist/cli.js.map +0 -53
  140. package/dist/index.d.ts +0 -2
  141. package/dist/index.d.ts.map +0 -1
  142. package/dist/index.js +0 -2032
  143. package/dist/index.js.map +0 -48
  144. package/dist/src/ai/tools.d.ts.map +0 -1
  145. package/dist/src/ai/tools.js +0 -1656
  146. package/dist/src/ai/tools.js.map +0 -45
  147. package/dist/src/cli/auth-requirements.d.ts.map +0 -1
  148. package/dist/src/cli/auth-requirements.js +0 -66
  149. package/dist/src/cli/auth-requirements.js.map +0 -10
  150. package/dist/src/cli/auth-schemes.d.ts.map +0 -1
  151. package/dist/src/cli/auth-schemes.js +0 -116
  152. package/dist/src/cli/auth-schemes.js.map +0 -11
  153. package/dist/src/cli/capabilities.d.ts.map +0 -1
  154. package/dist/src/cli/capabilities.js +0 -45
  155. package/dist/src/cli/capabilities.js.map +0 -10
  156. package/dist/src/cli/command-id.d.ts.map +0 -1
  157. package/dist/src/cli/command-id.js +0 -18
  158. package/dist/src/cli/command-id.js.map +0 -11
  159. package/dist/src/cli/command-index.d.ts.map +0 -1
  160. package/dist/src/cli/command-index.js +0 -15
  161. package/dist/src/cli/command-index.js.map +0 -10
  162. package/dist/src/cli/command-model.d.ts.map +0 -1
  163. package/dist/src/cli/command-model.js +0 -274
  164. package/dist/src/cli/command-model.js.map +0 -18
  165. package/dist/src/cli/compile.d.ts.map +0 -1
  166. package/dist/src/cli/compile.js +0 -146
  167. package/dist/src/cli/compile.js.map +0 -11
  168. package/dist/src/cli/crypto.d.ts.map +0 -1
  169. package/dist/src/cli/crypto.js +0 -15
  170. package/dist/src/cli/crypto.js.map +0 -10
  171. package/dist/src/cli/derive-name.d.ts.map +0 -1
  172. package/dist/src/cli/derive-name.js +0 -70
  173. package/dist/src/cli/derive-name.js.map +0 -10
  174. package/dist/src/cli/exec.d.ts.map +0 -1
  175. package/dist/src/cli/exec.js +0 -2077
  176. package/dist/src/cli/exec.js.map +0 -49
  177. package/dist/src/cli/main.d.ts.map +0 -1
  178. package/dist/src/cli/main.js +0 -2032
  179. package/dist/src/cli/main.js.map +0 -48
  180. package/dist/src/cli/naming.d.ts.map +0 -1
  181. package/dist/src/cli/naming.js +0 -216
  182. package/dist/src/cli/naming.js.map +0 -12
  183. package/dist/src/cli/operations.d.ts.map +0 -1
  184. package/dist/src/cli/operations.js +0 -103
  185. package/dist/src/cli/operations.js.map +0 -10
  186. package/dist/src/cli/params.d.ts.map +0 -1
  187. package/dist/src/cli/params.js +0 -79
  188. package/dist/src/cli/params.js.map +0 -12
  189. package/dist/src/cli/pluralize.d.ts.map +0 -1
  190. package/dist/src/cli/pluralize.js +0 -43
  191. package/dist/src/cli/pluralize.js.map +0 -10
  192. package/dist/src/cli/positional.d.ts.map +0 -1
  193. package/dist/src/cli/positional.js +0 -39
  194. package/dist/src/cli/positional.js.map +0 -10
  195. package/dist/src/cli/request-body.d.ts.map +0 -1
  196. package/dist/src/cli/request-body.js +0 -82
  197. package/dist/src/cli/request-body.js.map +0 -12
  198. package/dist/src/cli/runtime/argv.d.ts.map +0 -1
  199. package/dist/src/cli/runtime/argv.js +0 -22
  200. package/dist/src/cli/runtime/argv.js.map +0 -10
  201. package/dist/src/cli/runtime/auth/resolve.d.ts.map +0 -1
  202. package/dist/src/cli/runtime/auth/resolve.js +0 -38
  203. package/dist/src/cli/runtime/auth/resolve.js.map +0 -10
  204. package/dist/src/cli/runtime/body-flags.d.ts.map +0 -1
  205. package/dist/src/cli/runtime/body-flags.js +0 -86
  206. package/dist/src/cli/runtime/body-flags.js.map +0 -10
  207. package/dist/src/cli/runtime/body.d.ts.map +0 -1
  208. package/dist/src/cli/runtime/body.js +0 -40
  209. package/dist/src/cli/runtime/body.js.map +0 -11
  210. package/dist/src/cli/runtime/collect.d.ts.map +0 -1
  211. package/dist/src/cli/runtime/collect.js +0 -9
  212. package/dist/src/cli/runtime/collect.js.map +0 -10
  213. package/dist/src/cli/runtime/compat.d.ts.map +0 -1
  214. package/dist/src/cli/runtime/compat.js +0 -62
  215. package/dist/src/cli/runtime/compat.js.map +0 -10
  216. package/dist/src/cli/runtime/context.d.ts.map +0 -1
  217. package/dist/src/cli/runtime/context.js +0 -936
  218. package/dist/src/cli/runtime/context.js.map +0 -32
  219. package/dist/src/cli/runtime/execute.d.ts.map +0 -1
  220. package/dist/src/cli/runtime/execute.js +0 -670
  221. package/dist/src/cli/runtime/execute.js.map +0 -22
  222. package/dist/src/cli/runtime/generated.d.ts.map +0 -1
  223. package/dist/src/cli/runtime/generated.js +0 -869
  224. package/dist/src/cli/runtime/generated.js.map +0 -23
  225. package/dist/src/cli/runtime/headers.d.ts.map +0 -1
  226. package/dist/src/cli/runtime/headers.js +0 -36
  227. package/dist/src/cli/runtime/headers.js.map +0 -10
  228. package/dist/src/cli/runtime/index.d.ts.map +0 -1
  229. package/dist/src/cli/runtime/index.js +0 -1808
  230. package/dist/src/cli/runtime/index.js.map +0 -46
  231. package/dist/src/cli/runtime/profile/secrets.d.ts.map +0 -1
  232. package/dist/src/cli/runtime/profile/secrets.js +0 -51
  233. package/dist/src/cli/runtime/profile/secrets.js.map +0 -11
  234. package/dist/src/cli/runtime/profile/store.d.ts.map +0 -1
  235. package/dist/src/cli/runtime/profile/store.js +0 -102
  236. package/dist/src/cli/runtime/profile/store.js.map +0 -11
  237. package/dist/src/cli/runtime/request.d.ts.map +0 -1
  238. package/dist/src/cli/runtime/request.js +0 -571
  239. package/dist/src/cli/runtime/request.js.map +0 -21
  240. package/dist/src/cli/runtime/server-url.d.ts.map +0 -1
  241. package/dist/src/cli/runtime/server-url.js +0 -55
  242. package/dist/src/cli/runtime/server-url.js.map +0 -11
  243. package/dist/src/cli/runtime/template.d.ts.map +0 -1
  244. package/dist/src/cli/runtime/template.js +0 -29
  245. package/dist/src/cli/runtime/template.js.map +0 -10
  246. package/dist/src/cli/runtime/validate/ajv.d.ts +0 -3
  247. package/dist/src/cli/runtime/validate/ajv.d.ts.map +0 -1
  248. package/dist/src/cli/runtime/validate/ajv.js +0 -17
  249. package/dist/src/cli/runtime/validate/ajv.js.map +0 -10
  250. package/dist/src/cli/runtime/validate/coerce.d.ts.map +0 -1
  251. package/dist/src/cli/runtime/validate/coerce.js +0 -60
  252. package/dist/src/cli/runtime/validate/coerce.js.map +0 -10
  253. package/dist/src/cli/runtime/validate/error.d.ts.map +0 -1
  254. package/dist/src/cli/runtime/validate/error.js +0 -21
  255. package/dist/src/cli/runtime/validate/error.js.map +0 -10
  256. package/dist/src/cli/runtime/validate/index.d.ts.map +0 -1
  257. package/dist/src/cli/runtime/validate/index.js +0 -122
  258. package/dist/src/cli/runtime/validate/index.js.map +0 -13
  259. package/dist/src/cli/runtime/validate/schema.d.ts.map +0 -1
  260. package/dist/src/cli/runtime/validate/schema.js +0 -36
  261. package/dist/src/cli/runtime/validate/schema.js.map +0 -10
  262. package/dist/src/cli/schema-shape.d.ts.map +0 -1
  263. package/dist/src/cli/schema-shape.js +0 -41
  264. package/dist/src/cli/schema-shape.js.map +0 -10
  265. package/dist/src/cli/schema.d.ts.map +0 -1
  266. package/dist/src/cli/schema.js +0 -38
  267. package/dist/src/cli/schema.js.map +0 -10
  268. package/dist/src/cli/server.d.ts.map +0 -1
  269. package/dist/src/cli/server.js +0 -64
  270. package/dist/src/cli/server.js.map +0 -11
  271. package/dist/src/cli/spec-id.d.ts.map +0 -1
  272. package/dist/src/cli/spec-id.js +0 -21
  273. package/dist/src/cli/spec-id.js.map +0 -11
  274. package/dist/src/cli/spec-loader.d.ts.map +0 -1
  275. package/dist/src/cli/spec-loader.js +0 -110
  276. package/dist/src/cli/spec-loader.js.map +0 -15
  277. package/dist/src/cli/stable-json.d.ts.map +0 -1
  278. package/dist/src/cli/stable-json.js +0 -35
  279. package/dist/src/cli/stable-json.js.map +0 -10
  280. package/dist/src/cli/strings.d.ts.map +0 -1
  281. package/dist/src/cli/strings.js +0 -16
  282. package/dist/src/cli/strings.js.map +0 -10
  283. package/dist/src/cli/types.d.ts.map +0 -1
  284. package/dist/src/cli/types.js +0 -9
  285. package/dist/src/cli/types.js.map +0 -10
  286. package/index.ts +0 -1
  287. package/src/ai/tools.ts +0 -211
  288. package/src/cli/auth-requirements.ts +0 -91
  289. package/src/cli/auth-schemes.ts +0 -187
  290. package/src/cli/capabilities.ts +0 -88
  291. package/src/cli/command-id.ts +0 -16
  292. package/src/cli/command-index.ts +0 -19
  293. package/src/cli/command-model.ts +0 -128
  294. package/src/cli/compile.ts +0 -101
  295. package/src/cli/crypto.ts +0 -9
  296. package/src/cli/derive-name.ts +0 -101
  297. package/src/cli/exec.ts +0 -72
  298. package/src/cli/main.ts +0 -231
  299. package/src/cli/naming.ts +0 -224
  300. package/src/cli/operations.ts +0 -152
  301. package/src/cli/params.ts +0 -71
  302. package/src/cli/pluralize.ts +0 -41
  303. package/src/cli/positional.ts +0 -75
  304. package/src/cli/request-body.ts +0 -94
  305. package/src/cli/runtime/argv.ts +0 -14
  306. package/src/cli/runtime/auth/resolve.ts +0 -59
  307. package/src/cli/runtime/body-flags.ts +0 -176
  308. package/src/cli/runtime/body.ts +0 -24
  309. package/src/cli/runtime/collect.ts +0 -6
  310. package/src/cli/runtime/compat.ts +0 -89
  311. package/src/cli/runtime/context.ts +0 -62
  312. package/src/cli/runtime/execute.ts +0 -147
  313. package/src/cli/runtime/generated.ts +0 -242
  314. package/src/cli/runtime/headers.ts +0 -37
  315. package/src/cli/runtime/index.ts +0 -3
  316. package/src/cli/runtime/profile/secrets.ts +0 -83
  317. package/src/cli/runtime/profile/store.ts +0 -100
  318. package/src/cli/runtime/request.ts +0 -390
  319. package/src/cli/runtime/server-url.ts +0 -45
  320. package/src/cli/runtime/template.ts +0 -26
  321. package/src/cli/runtime/validate/ajv.ts +0 -13
  322. package/src/cli/runtime/validate/coerce.ts +0 -71
  323. package/src/cli/runtime/validate/error.ts +0 -29
  324. package/src/cli/runtime/validate/index.ts +0 -4
  325. package/src/cli/runtime/validate/schema.ts +0 -54
  326. package/src/cli/schema-shape.ts +0 -36
  327. package/src/cli/schema.ts +0 -76
  328. package/src/cli/server.ts +0 -88
  329. package/src/cli/spec-id.ts +0 -12
  330. package/src/cli/spec-loader.ts +0 -58
  331. package/src/cli/stable-json.ts +0 -35
  332. package/src/cli/strings.ts +0 -21
  333. package/src/cli/types.ts +0 -59
  334. package/src/macros/env.ts +0 -21
  335. package/src/macros/spec.ts +0 -17
@@ -1,59 +0,0 @@
1
- import type { AuthScheme } from "../../auth-schemes.ts";
2
-
3
- export type AuthInputs = {
4
- flagAuthScheme?: string;
5
- profileAuthScheme?: string;
6
- embeddedAuthScheme?: string;
7
- hasStoredToken?: boolean;
8
- };
9
-
10
- const BEARER_COMPATIBLE_KINDS = new Set([
11
- "http-bearer",
12
- "oauth2",
13
- "openIdConnect",
14
- ]);
15
-
16
- export function resolveAuthScheme(
17
- authSchemes: AuthScheme[],
18
- required: import("../../auth-requirements.ts").AuthSummary,
19
- inputs: AuthInputs,
20
- ): string | undefined {
21
- // Priority: CLI flag > profile > embedded default
22
- if (inputs.flagAuthScheme) return inputs.flagAuthScheme;
23
-
24
- if (
25
- inputs.profileAuthScheme &&
26
- authSchemes.some((s) => s.key === inputs.profileAuthScheme)
27
- ) {
28
- return inputs.profileAuthScheme;
29
- }
30
-
31
- if (
32
- inputs.embeddedAuthScheme &&
33
- authSchemes.some((s) => s.key === inputs.embeddedAuthScheme)
34
- ) {
35
- return inputs.embeddedAuthScheme;
36
- }
37
-
38
- // If operation requires exactly one scheme, choose it.
39
- const alts = required.alternatives;
40
- if (alts.length === 1 && alts[0]?.length === 1) return alts[0][0]?.key;
41
-
42
- // Otherwise if there is only one scheme in spec, pick it.
43
- if (authSchemes.length === 1) return authSchemes[0]?.key;
44
-
45
- // If user has a stored token and operation accepts a bearer-compatible scheme,
46
- // automatically pick the first one that matches.
47
- if (inputs.hasStoredToken && alts.length > 0) {
48
- for (const alt of alts) {
49
- if (alt.length !== 1) continue;
50
- const key = alt[0]?.key;
51
- const scheme = authSchemes.find((s) => s.key === key);
52
- if (scheme && BEARER_COMPATIBLE_KINDS.has(scheme.kind)) {
53
- return key;
54
- }
55
- }
56
- }
57
-
58
- return undefined;
59
- }
@@ -1,176 +0,0 @@
1
- /**
2
- * Body flag generation and parsing utilities.
3
- *
4
- * Generates CLI flags from JSON schema properties and parses
5
- * dot-notation flags back into nested objects.
6
- */
7
-
8
- type JsonSchema = {
9
- type?: string;
10
- properties?: Record<string, JsonSchema>;
11
- items?: JsonSchema;
12
- required?: string[];
13
- description?: string;
14
- };
15
-
16
- export type BodyFlagDef = {
17
- flag: string; // e.g. "--name" or "--address.street"
18
- path: string[]; // e.g. ["name"] or ["address", "street"]
19
- type: "string" | "number" | "integer" | "boolean";
20
- description: string;
21
- required: boolean;
22
- };
23
-
24
- /**
25
- * Generate flag definitions from a JSON schema.
26
- * Recursively handles nested objects using dot notation.
27
- */
28
- export function generateBodyFlags(
29
- schema: JsonSchema | undefined,
30
- reservedFlags: Set<string>,
31
- ): BodyFlagDef[] {
32
- if (!schema || schema.type !== "object" || !schema.properties) {
33
- return [];
34
- }
35
-
36
- const flags: BodyFlagDef[] = [];
37
- const requiredSet = new Set(schema.required ?? []);
38
-
39
- collectFlags(schema.properties, [], requiredSet, flags, reservedFlags);
40
-
41
- return flags;
42
- }
43
-
44
- function collectFlags(
45
- properties: Record<string, JsonSchema>,
46
- pathPrefix: string[],
47
- requiredAtRoot: Set<string>,
48
- out: BodyFlagDef[],
49
- reservedFlags: Set<string>,
50
- ): void {
51
- for (const [name, propSchema] of Object.entries(properties)) {
52
- if (!name || typeof name !== "string") continue;
53
- if (!propSchema || typeof propSchema !== "object") continue;
54
-
55
- const path = [...pathPrefix, name];
56
- const flagName = `--${path.join(".")}`;
57
-
58
- // Skip if this flag would conflict with an operation parameter
59
- if (reservedFlags.has(flagName)) continue;
60
-
61
- const t = propSchema.type;
62
-
63
- if (t === "object" && propSchema.properties) {
64
- // Recurse into nested object
65
- const nestedRequired = new Set(propSchema.required ?? []);
66
- collectFlags(
67
- propSchema.properties,
68
- path,
69
- nestedRequired,
70
- out,
71
- reservedFlags,
72
- );
73
- } else if (
74
- t === "string" ||
75
- t === "number" ||
76
- t === "integer" ||
77
- t === "boolean"
78
- ) {
79
- // Leaf property - generate a flag
80
- const isRequired =
81
- pathPrefix.length === 0 ? requiredAtRoot.has(name) : false;
82
-
83
- out.push({
84
- flag: flagName,
85
- path,
86
- type: t,
87
- description: propSchema.description ?? `Body field '${path.join(".")}'`,
88
- required: isRequired,
89
- });
90
- }
91
- // Skip arrays and other complex types for now
92
- }
93
- }
94
-
95
- /**
96
- * Parse flag values with dot notation into a nested object.
97
- *
98
- * Example:
99
- * { "address.street": "123 Main", "address.city": "NYC", "name": "Ada" }
100
- * Becomes:
101
- * { address: { street: "123 Main", city: "NYC" }, name: "Ada" }
102
- */
103
- export function parseDotNotationFlags(
104
- flagValues: Record<string, unknown>,
105
- flagDefs: BodyFlagDef[],
106
- ): Record<string, unknown> {
107
- const result: Record<string, unknown> = {};
108
-
109
- for (const def of flagDefs) {
110
- // Commander keeps dots in option names: --address.street -> "address.street"
111
- const dotKey = def.path.join(".");
112
- const value = flagValues[dotKey];
113
-
114
- if (value === undefined) continue;
115
-
116
- setNestedValue(result, def.path, value, def.type);
117
- }
118
-
119
- return result;
120
- }
121
-
122
- /**
123
- * Set a value at a nested path, creating intermediate objects as needed.
124
- */
125
- function setNestedValue(
126
- obj: Record<string, unknown>,
127
- path: string[],
128
- value: unknown,
129
- type: string,
130
- ): void {
131
- let current = obj;
132
-
133
- for (let i = 0; i < path.length - 1; i++) {
134
- const key = path[i] as string;
135
- if (!(key in current) || typeof current[key] !== "object") {
136
- current[key] = {};
137
- }
138
- current = current[key] as Record<string, unknown>;
139
- }
140
-
141
- const finalKey = path[path.length - 1] as string;
142
-
143
- // Coerce value based on type
144
- if (type === "boolean") {
145
- current[finalKey] = true;
146
- } else if (type === "integer") {
147
- current[finalKey] = Number.parseInt(String(value), 10);
148
- } else if (type === "number") {
149
- current[finalKey] = Number(String(value));
150
- } else {
151
- current[finalKey] = String(value);
152
- }
153
- }
154
-
155
- /**
156
- * Check if all required fields are present.
157
- * Returns list of missing field paths.
158
- */
159
- export function findMissingRequired(
160
- flagValues: Record<string, unknown>,
161
- flagDefs: BodyFlagDef[],
162
- ): string[] {
163
- const missing: string[] = [];
164
-
165
- for (const def of flagDefs) {
166
- if (!def.required) continue;
167
-
168
- // Commander keeps dots in option names: --address.street -> "address.street"
169
- const dotKey = def.path.join(".");
170
- if (flagValues[dotKey] === undefined) {
171
- missing.push(dotKey);
172
- }
173
- }
174
-
175
- return missing;
176
- }
@@ -1,24 +0,0 @@
1
- import { parseYamlContent, readFileText } from "./compat.ts";
2
-
3
- export type BodyInput =
4
- | { kind: "none" }
5
- | { kind: "data"; data: string }
6
- | { kind: "file"; path: string };
7
-
8
- export async function loadBody(
9
- input: BodyInput,
10
- ): Promise<{ raw: string; json?: unknown } | undefined> {
11
- if (input.kind === "none") return undefined;
12
- if (input.kind === "data") return { raw: input.data };
13
-
14
- const text = await readFileText(input.path);
15
- return { raw: text };
16
- }
17
-
18
- export function parseBodyAsJsonOrYaml(text: string): unknown {
19
- const trimmed = text.trimStart();
20
- if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
21
- return JSON.parse(text);
22
- }
23
- return parseYamlContent(text);
24
- }
@@ -1,6 +0,0 @@
1
- export function collectRepeatable(
2
- value: string,
3
- previous: string[] | undefined,
4
- ): string[] {
5
- return [...(previous ?? []), value];
6
- }
@@ -1,89 +0,0 @@
1
- /**
2
- * Cross-runtime compatibility utilities for Bun and Node.js
3
- *
4
- * This module provides abstractions over Bun-specific APIs to allow
5
- * the exec command to run in Node.js while compile remains Bun-only.
6
- */
7
-
8
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
- import { parse as parseYaml } from "yaml";
10
-
11
- /**
12
- * Detect if we're running in Bun
13
- */
14
- export const isBun = typeof globalThis.Bun !== "undefined";
15
-
16
- /**
17
- * Read a file's text content - works in both Bun and Node.js
18
- */
19
- export async function readFileText(path: string): Promise<string> {
20
- if (isBun) {
21
- return Bun.file(path).text();
22
- }
23
- return readFileSync(path, "utf-8");
24
- }
25
-
26
- /**
27
- * Check if a file exists - works in both Bun and Node.js
28
- */
29
- export async function fileExists(path: string): Promise<boolean> {
30
- if (isBun) {
31
- return Bun.file(path).exists();
32
- }
33
- return existsSync(path);
34
- }
35
-
36
- /**
37
- * Write text to a file - works in both Bun and Node.js
38
- */
39
- export async function writeFileText(
40
- path: string,
41
- content: string,
42
- ): Promise<void> {
43
- if (isBun) {
44
- await Bun.write(path, content);
45
- return;
46
- }
47
- writeFileSync(path, content, "utf-8");
48
- }
49
-
50
- /**
51
- * Create directory recursively - works in both Bun and Node.js
52
- */
53
- export async function mkdirp(path: string): Promise<void> {
54
- if (isBun) {
55
- await Bun.$`mkdir -p ${path}`;
56
- return;
57
- }
58
- mkdirSync(path, { recursive: true });
59
- }
60
-
61
- /**
62
- * Parse YAML content - works in both Bun and Node.js
63
- */
64
- export function parseYamlContent(text: string): unknown {
65
- if (isBun) {
66
- const { YAML } = globalThis.Bun;
67
- return YAML.parse(text);
68
- }
69
- return parseYaml(text);
70
- }
71
-
72
- /**
73
- * Read from stdin - works in both Bun and Node.js
74
- */
75
- export async function readStdinText(): Promise<string> {
76
- if (isBun) {
77
- return Bun.stdin.text();
78
- }
79
- // Node.js stdin reading
80
- return new Promise((resolve, reject) => {
81
- let data = "";
82
- process.stdin.setEncoding("utf8");
83
- process.stdin.on("data", (chunk) => {
84
- data += chunk;
85
- });
86
- process.stdin.on("end", () => resolve(data));
87
- process.stdin.on("error", reject);
88
- });
89
- }
@@ -1,62 +0,0 @@
1
- import { listAuthSchemes } from "../auth-schemes.ts";
2
- import { deriveCapabilities } from "../capabilities.ts";
3
- import { buildCommandsIndex } from "../command-index.ts";
4
- import { buildCommandModel } from "../command-model.ts";
5
- import { planOperations } from "../naming.ts";
6
- import { indexOperations } from "../operations.ts";
7
- import { buildSchemaOutput } from "../schema.ts";
8
- import { listServers } from "../server.ts";
9
- import { loadSpec } from "../spec-loader.ts";
10
-
11
- export type BuildRuntimeContextOptions = {
12
- spec?: string;
13
- embeddedSpecText?: string;
14
- };
15
-
16
- export async function buildRuntimeContext(options: BuildRuntimeContextOptions) {
17
- const loaded = await loadSpec({
18
- spec: options.spec,
19
- embeddedSpecText: options.embeddedSpecText,
20
- });
21
-
22
- const operations = indexOperations(loaded.doc);
23
- const servers = listServers(loaded.doc);
24
- const authSchemes = listAuthSchemes(loaded.doc);
25
- const planned = planOperations(operations);
26
- const commands = buildCommandModel(planned, {
27
- specId: loaded.id,
28
- globalSecurity: loaded.doc.security,
29
- authSchemes,
30
- });
31
- const commandsIndex = buildCommandsIndex(commands);
32
- const capabilities = deriveCapabilities({
33
- doc: loaded.doc,
34
- servers,
35
- authSchemes,
36
- operations,
37
- commands,
38
- });
39
-
40
- const schema = buildSchemaOutput(
41
- loaded,
42
- operations,
43
- planned,
44
- servers,
45
- authSchemes,
46
- commands,
47
- commandsIndex,
48
- capabilities,
49
- );
50
-
51
- return {
52
- loaded,
53
- operations,
54
- servers,
55
- authSchemes,
56
- planned,
57
- commands,
58
- commandsIndex,
59
- capabilities,
60
- schema,
61
- };
62
- }
@@ -1,147 +0,0 @@
1
- import type { CommandAction } from "../command-model.ts";
2
-
3
- import type { BodyFlagDef } from "./body-flags.ts";
4
- import { buildRequest, type EmbeddedDefaults } from "./request.ts";
5
-
6
- export type ExecuteInput = {
7
- action: CommandAction;
8
- positionalValues: string[];
9
- flagValues: Record<string, unknown>;
10
- globals: import("./request.ts").RuntimeGlobals;
11
- servers: import("../server.ts").ServerInfo[];
12
- authSchemes: import("../auth-schemes.ts").AuthScheme[];
13
- specId: string;
14
- embeddedDefaults?: EmbeddedDefaults;
15
- bodyFlagDefs?: BodyFlagDef[];
16
- /** Resource name for error messages (e.g. "plans") */
17
- resourceName?: string;
18
- };
19
-
20
- export type ExecuteResult = {
21
- ok: boolean;
22
- status: number;
23
- body: unknown;
24
- curl: string;
25
- };
26
-
27
- /**
28
- * Format an error message with a help hint.
29
- */
30
- function formatError(
31
- message: string,
32
- resourceName: string | undefined,
33
- actionName: string,
34
- ): string {
35
- const helpCmd = resourceName
36
- ? `${resourceName} ${actionName} --help`
37
- : `${actionName} --help`;
38
- return `${message}\n\nRun '${helpCmd}' to see available options.`;
39
- }
40
-
41
- /**
42
- * Execute an action and return the result as data.
43
- * This is the core execution function used by both CLI and programmatic API.
44
- */
45
- export async function execute(
46
- input: Omit<ExecuteInput, "resourceName">,
47
- ): Promise<ExecuteResult> {
48
- const { request, curl } = await buildRequest({
49
- specId: input.specId,
50
- action: input.action,
51
- positionalValues: input.positionalValues,
52
- flagValues: input.flagValues,
53
- globals: input.globals,
54
- servers: input.servers,
55
- authSchemes: input.authSchemes,
56
- embeddedDefaults: input.embeddedDefaults,
57
- bodyFlagDefs: input.bodyFlagDefs,
58
- });
59
-
60
- const res = await fetch(request);
61
- const contentType = res.headers.get("content-type") ?? "";
62
-
63
- const text = await res.text();
64
- let body: unknown = text;
65
-
66
- if (contentType.includes("json") && text) {
67
- try {
68
- body = JSON.parse(text);
69
- } catch {
70
- // keep as text
71
- }
72
- }
73
-
74
- return {
75
- ok: res.ok,
76
- status: res.status,
77
- body,
78
- curl,
79
- };
80
- }
81
-
82
- /**
83
- * Execute an action and write output to stdout/stderr.
84
- * This is the CLI-facing wrapper around execute().
85
- */
86
- export async function executeAction(input: ExecuteInput): Promise<void> {
87
- const actionName = input.action.action;
88
- const resourceName = input.resourceName;
89
-
90
- try {
91
- if (input.globals.curl) {
92
- const { curl } = await buildRequest({
93
- specId: input.specId,
94
- action: input.action,
95
- positionalValues: input.positionalValues,
96
- flagValues: input.flagValues,
97
- globals: input.globals,
98
- servers: input.servers,
99
- authSchemes: input.authSchemes,
100
- embeddedDefaults: input.embeddedDefaults,
101
- bodyFlagDefs: input.bodyFlagDefs,
102
- });
103
- process.stdout.write(`${curl}\n`);
104
- return;
105
- }
106
-
107
- const result = await execute(input);
108
-
109
- if (!result.ok) {
110
- if (input.globals.json) {
111
- process.stdout.write(
112
- `${JSON.stringify({ status: result.status, body: result.body })}\n`,
113
- );
114
- } else {
115
- process.stderr.write(`HTTP ${result.status}\n`);
116
- process.stderr.write(
117
- `${typeof result.body === "string" ? result.body : JSON.stringify(result.body, null, 2)}\n`,
118
- );
119
- }
120
- process.exitCode = 1;
121
- return;
122
- }
123
-
124
- if (input.globals.json) {
125
- process.stdout.write(`${JSON.stringify(result.body)}\n`);
126
- return;
127
- }
128
-
129
- // default (human + agent readable)
130
- if (typeof result.body === "string") {
131
- process.stdout.write(result.body);
132
- if (!result.body.endsWith("\n")) process.stdout.write("\n");
133
- } else {
134
- process.stdout.write(`${JSON.stringify(result.body, null, 2)}\n`);
135
- }
136
- } catch (err) {
137
- const rawMessage = err instanceof Error ? err.message : String(err);
138
- const message = formatError(rawMessage, resourceName, actionName);
139
-
140
- if (input.globals.json) {
141
- process.stdout.write(`${JSON.stringify({ error: rawMessage })}\n`);
142
- } else {
143
- process.stderr.write(`error: ${message}\n`);
144
- }
145
- process.exitCode = 1;
146
- }
147
- }