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
@@ -17,4 +17,3 @@ export type RequestBodyInfo = {
17
17
  preferredSchema?: JsonSchema;
18
18
  };
19
19
  export declare function deriveRequestBodyInfo(op: NormalizedOperation): RequestBodyInfo | undefined;
20
- //# sourceMappingURL=request-body.d.ts.map
@@ -0,0 +1,44 @@
1
+ import { getSchemaEnumStrings, getSchemaFormat, getSchemaType, } from "./schema-shape.js";
2
+ import { isJsonSchema } from "./types.js";
3
+ function getRequestBody(op) {
4
+ return op.requestBody;
5
+ }
6
+ export function deriveRequestBodyInfo(op) {
7
+ const rb = getRequestBody(op);
8
+ if (!rb)
9
+ return undefined;
10
+ const content = [];
11
+ for (const contentType of rb.contentTypes) {
12
+ const schema = rb.schemasByContentType[contentType];
13
+ content.push({
14
+ contentType,
15
+ required: rb.required,
16
+ schemaType: getSchemaType(schema),
17
+ schemaFormat: getSchemaFormat(schema),
18
+ schemaEnum: getSchemaEnumStrings(schema),
19
+ });
20
+ }
21
+ content.sort((a, b) => a.contentType.localeCompare(b.contentType));
22
+ const hasJson = content.some((c) => c.contentType.includes("json"));
23
+ const hasFormUrlEncoded = content.some((c) => c.contentType === "application/x-www-form-urlencoded");
24
+ const hasMultipart = content.some((c) => c.contentType.startsWith("multipart/"));
25
+ const bodyFlags = ["--data", "--file"]; // always available when requestBody exists
26
+ const preferredContentType = content.find((c) => c.contentType === "application/json")?.contentType ??
27
+ content.find((c) => c.contentType.includes("json"))?.contentType ??
28
+ content[0]?.contentType;
29
+ const preferredSchema = preferredContentType
30
+ ? rb.schemasByContentType[preferredContentType]
31
+ : undefined;
32
+ return {
33
+ required: rb.required,
34
+ content,
35
+ hasJson,
36
+ hasFormUrlEncoded,
37
+ hasMultipart,
38
+ bodyFlags,
39
+ preferredContentType,
40
+ preferredSchema: isJsonSchema(preferredSchema)
41
+ ? preferredSchema
42
+ : undefined,
43
+ };
44
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { deriveRequestBodyInfo } from "./request-body.js";
3
+ describe("deriveRequestBodyInfo", () => {
4
+ test("summarizes content types and convenience flags", () => {
5
+ const op = {
6
+ key: "POST /contacts",
7
+ method: "POST",
8
+ path: "/contacts",
9
+ tags: [],
10
+ parameters: [],
11
+ requestBody: {
12
+ required: true,
13
+ contentTypes: ["application/x-www-form-urlencoded", "application/json"],
14
+ schemasByContentType: {
15
+ "application/json": { type: "object" },
16
+ "application/x-www-form-urlencoded": { type: "object" },
17
+ },
18
+ },
19
+ };
20
+ const info = deriveRequestBodyInfo(op);
21
+ expect(info?.required).toBe(true);
22
+ expect(info?.hasJson).toBe(true);
23
+ expect(info?.hasFormUrlEncoded).toBe(true);
24
+ expect(info?.hasMultipart).toBe(false);
25
+ expect(info?.content.map((c) => c.contentType)).toEqual([
26
+ "application/json",
27
+ "application/x-www-form-urlencoded",
28
+ ]);
29
+ expect(info?.preferredSchema).toEqual({ type: "object" });
30
+ });
31
+ });
@@ -1,3 +1,2 @@
1
1
  export declare function getArgValue(argv: string[], key: string): string | undefined;
2
2
  export declare function hasAnyArg(argv: string[], names: string[]): boolean;
3
- //# sourceMappingURL=argv.d.ts.map
@@ -0,0 +1,15 @@
1
+ export function getArgValue(argv, key) {
2
+ for (let i = 0; i < argv.length; i++) {
3
+ const a = argv[i];
4
+ if (!a)
5
+ continue;
6
+ if (a === key)
7
+ return argv[i + 1];
8
+ if (a.startsWith(`${key}=`))
9
+ return a.slice(key.length + 1);
10
+ }
11
+ return undefined;
12
+ }
13
+ export function hasAnyArg(argv, names) {
14
+ return argv.some((a) => a && names.includes(a));
15
+ }
@@ -6,4 +6,3 @@ export type AuthInputs = {
6
6
  hasStoredToken?: boolean;
7
7
  };
8
8
  export declare function resolveAuthScheme(authSchemes: AuthScheme[], required: import("../../auth-requirements.js").AuthSummary, inputs: AuthInputs): string | undefined;
9
- //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1,39 @@
1
+ const BEARER_COMPATIBLE_KINDS = new Set([
2
+ "http-bearer",
3
+ "oauth2",
4
+ "openIdConnect",
5
+ ]);
6
+ export function resolveAuthScheme(authSchemes, required, inputs) {
7
+ // Priority: CLI flag > profile > embedded default
8
+ if (inputs.flagAuthScheme)
9
+ return inputs.flagAuthScheme;
10
+ if (inputs.profileAuthScheme &&
11
+ authSchemes.some((s) => s.key === inputs.profileAuthScheme)) {
12
+ return inputs.profileAuthScheme;
13
+ }
14
+ if (inputs.embeddedAuthScheme &&
15
+ authSchemes.some((s) => s.key === inputs.embeddedAuthScheme)) {
16
+ return inputs.embeddedAuthScheme;
17
+ }
18
+ // If operation requires exactly one scheme, choose it.
19
+ const alts = required.alternatives;
20
+ if (alts.length === 1 && alts[0]?.length === 1)
21
+ return alts[0][0]?.key;
22
+ // Otherwise if there is only one scheme in spec, pick it.
23
+ if (authSchemes.length === 1)
24
+ return authSchemes[0]?.key;
25
+ // If user has a stored token and operation accepts a bearer-compatible scheme,
26
+ // automatically pick the first one that matches.
27
+ if (inputs.hasStoredToken && alts.length > 0) {
28
+ for (const alt of alts) {
29
+ if (alt.length !== 1)
30
+ continue;
31
+ const key = alt[0]?.key;
32
+ const scheme = authSchemes.find((s) => s.key === key);
33
+ if (scheme && BEARER_COMPATIBLE_KINDS.has(scheme.kind)) {
34
+ return key;
35
+ }
36
+ }
37
+ }
38
+ return undefined;
39
+ }
@@ -38,4 +38,3 @@ export declare function parseDotNotationFlags(flagValues: Record<string, unknown
38
38
  */
39
39
  export declare function findMissingRequired(flagValues: Record<string, unknown>, flagDefs: BodyFlagDef[]): string[];
40
40
  export {};
41
- //# sourceMappingURL=body-flags.d.ts.map
@@ -0,0 +1,117 @@
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
+ * Generate flag definitions from a JSON schema.
9
+ * Recursively handles nested objects using dot notation.
10
+ */
11
+ export function generateBodyFlags(schema, reservedFlags) {
12
+ if (!schema || schema.type !== "object" || !schema.properties) {
13
+ return [];
14
+ }
15
+ const flags = [];
16
+ const requiredSet = new Set(schema.required ?? []);
17
+ collectFlags(schema.properties, [], requiredSet, flags, reservedFlags);
18
+ return flags;
19
+ }
20
+ function collectFlags(properties, pathPrefix, requiredAtRoot, out, reservedFlags) {
21
+ for (const [name, propSchema] of Object.entries(properties)) {
22
+ if (!name || typeof name !== "string")
23
+ continue;
24
+ if (!propSchema || typeof propSchema !== "object")
25
+ continue;
26
+ const path = [...pathPrefix, name];
27
+ const flagName = `--${path.join(".")}`;
28
+ // Skip if this flag would conflict with an operation parameter
29
+ if (reservedFlags.has(flagName))
30
+ continue;
31
+ const t = propSchema.type;
32
+ if (t === "object" && propSchema.properties) {
33
+ // Recurse into nested object
34
+ const nestedRequired = new Set(propSchema.required ?? []);
35
+ collectFlags(propSchema.properties, path, nestedRequired, out, reservedFlags);
36
+ }
37
+ else if (t === "string" ||
38
+ t === "number" ||
39
+ t === "integer" ||
40
+ t === "boolean") {
41
+ // Leaf property - generate a flag
42
+ const isRequired = pathPrefix.length === 0 ? requiredAtRoot.has(name) : false;
43
+ out.push({
44
+ flag: flagName,
45
+ path,
46
+ type: t,
47
+ description: propSchema.description ?? `Body field '${path.join(".")}'`,
48
+ required: isRequired,
49
+ });
50
+ }
51
+ // Skip arrays and other complex types for now
52
+ }
53
+ }
54
+ /**
55
+ * Parse flag values with dot notation into a nested object.
56
+ *
57
+ * Example:
58
+ * { "address.street": "123 Main", "address.city": "NYC", "name": "Ada" }
59
+ * Becomes:
60
+ * { address: { street: "123 Main", city: "NYC" }, name: "Ada" }
61
+ */
62
+ export function parseDotNotationFlags(flagValues, flagDefs) {
63
+ const result = {};
64
+ for (const def of flagDefs) {
65
+ // Commander keeps dots in option names: --address.street -> "address.street"
66
+ const dotKey = def.path.join(".");
67
+ const value = flagValues[dotKey];
68
+ if (value === undefined)
69
+ continue;
70
+ setNestedValue(result, def.path, value, def.type);
71
+ }
72
+ return result;
73
+ }
74
+ /**
75
+ * Set a value at a nested path, creating intermediate objects as needed.
76
+ */
77
+ function setNestedValue(obj, path, value, type) {
78
+ let current = obj;
79
+ for (let i = 0; i < path.length - 1; i++) {
80
+ const key = path[i];
81
+ if (!(key in current) || typeof current[key] !== "object") {
82
+ current[key] = {};
83
+ }
84
+ current = current[key];
85
+ }
86
+ const finalKey = path[path.length - 1];
87
+ // Coerce value based on type
88
+ if (type === "boolean") {
89
+ current[finalKey] = true;
90
+ }
91
+ else if (type === "integer") {
92
+ current[finalKey] = Number.parseInt(String(value), 10);
93
+ }
94
+ else if (type === "number") {
95
+ current[finalKey] = Number(String(value));
96
+ }
97
+ else {
98
+ current[finalKey] = String(value);
99
+ }
100
+ }
101
+ /**
102
+ * Check if all required fields are present.
103
+ * Returns list of missing field paths.
104
+ */
105
+ export function findMissingRequired(flagValues, flagDefs) {
106
+ const missing = [];
107
+ for (const def of flagDefs) {
108
+ if (!def.required)
109
+ continue;
110
+ // Commander keeps dots in option names: --address.street -> "address.street"
111
+ const dotKey = def.path.join(".");
112
+ if (flagValues[dotKey] === undefined) {
113
+ missing.push(dotKey);
114
+ }
115
+ }
116
+ return missing;
117
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,192 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { findMissingRequired, generateBodyFlags, parseDotNotationFlags, } from "./body-flags.js";
3
+ describe("generateBodyFlags", () => {
4
+ test("generates flags for simple properties", () => {
5
+ const flags = generateBodyFlags({
6
+ type: "object",
7
+ properties: {
8
+ name: { type: "string" },
9
+ age: { type: "integer" },
10
+ active: { type: "boolean" },
11
+ },
12
+ required: ["name"],
13
+ }, new Set());
14
+ expect(flags).toHaveLength(3);
15
+ expect(flags.find((f) => f.flag === "--name")).toEqual({
16
+ flag: "--name",
17
+ path: ["name"],
18
+ type: "string",
19
+ description: "Body field 'name'",
20
+ required: true,
21
+ });
22
+ expect(flags.find((f) => f.flag === "--age")).toEqual({
23
+ flag: "--age",
24
+ path: ["age"],
25
+ type: "integer",
26
+ description: "Body field 'age'",
27
+ required: false,
28
+ });
29
+ });
30
+ test("generates dot-notation flags for nested objects", () => {
31
+ const flags = generateBodyFlags({
32
+ type: "object",
33
+ properties: {
34
+ name: { type: "string" },
35
+ address: {
36
+ type: "object",
37
+ properties: {
38
+ street: { type: "string" },
39
+ city: { type: "string" },
40
+ zip: { type: "string" },
41
+ },
42
+ },
43
+ },
44
+ }, new Set());
45
+ expect(flags).toHaveLength(4);
46
+ expect(flags.find((f) => f.flag === "--name")).toBeDefined();
47
+ expect(flags.find((f) => f.flag === "--address.street")).toEqual({
48
+ flag: "--address.street",
49
+ path: ["address", "street"],
50
+ type: "string",
51
+ description: "Body field 'address.street'",
52
+ required: false,
53
+ });
54
+ });
55
+ test("handles deeply nested objects", () => {
56
+ const flags = generateBodyFlags({
57
+ type: "object",
58
+ properties: {
59
+ user: {
60
+ type: "object",
61
+ properties: {
62
+ profile: {
63
+ type: "object",
64
+ properties: {
65
+ bio: { type: "string" },
66
+ },
67
+ },
68
+ },
69
+ },
70
+ },
71
+ }, new Set());
72
+ expect(flags.find((f) => f.flag === "--user.profile.bio")).toEqual({
73
+ flag: "--user.profile.bio",
74
+ path: ["user", "profile", "bio"],
75
+ type: "string",
76
+ description: "Body field 'user.profile.bio'",
77
+ required: false,
78
+ });
79
+ });
80
+ test("skips reserved flags", () => {
81
+ const flags = generateBodyFlags({
82
+ type: "object",
83
+ properties: {
84
+ name: { type: "string" },
85
+ data: { type: "string" }, // --data is reserved
86
+ },
87
+ }, new Set(["--data"]));
88
+ expect(flags).toHaveLength(1);
89
+ expect(flags[0]?.flag).toBe("--name");
90
+ });
91
+ test("skips --curl builtin flag", () => {
92
+ const reservedFlags = new Set(["--curl"]);
93
+ const flags = generateBodyFlags({
94
+ type: "object",
95
+ properties: {
96
+ name: { type: "string" },
97
+ curl: { type: "boolean" }, // conflicts with --curl builtin
98
+ email: { type: "string" }, // no conflict
99
+ },
100
+ }, reservedFlags);
101
+ expect(flags).toHaveLength(2);
102
+ expect(flags.map((f) => f.flag).sort()).toEqual(["--email", "--name"]);
103
+ });
104
+ test("uses description from schema", () => {
105
+ const flags = generateBodyFlags({
106
+ type: "object",
107
+ properties: {
108
+ email: { type: "string", description: "User email address" },
109
+ },
110
+ }, new Set());
111
+ expect(flags[0]?.description).toBe("User email address");
112
+ });
113
+ });
114
+ describe("parseDotNotationFlags", () => {
115
+ test("parses flat flags", () => {
116
+ const flagDefs = generateBodyFlags({
117
+ type: "object",
118
+ properties: {
119
+ name: { type: "string" },
120
+ age: { type: "integer" },
121
+ },
122
+ }, new Set());
123
+ const result = parseDotNotationFlags({ name: "Ada", age: "30" }, flagDefs);
124
+ expect(result).toEqual({
125
+ name: "Ada",
126
+ age: 30,
127
+ });
128
+ });
129
+ test("parses nested flags into objects", () => {
130
+ const flagDefs = generateBodyFlags({
131
+ type: "object",
132
+ properties: {
133
+ name: { type: "string" },
134
+ address: {
135
+ type: "object",
136
+ properties: {
137
+ street: { type: "string" },
138
+ city: { type: "string" },
139
+ },
140
+ },
141
+ },
142
+ }, new Set());
143
+ // Commander keeps dots: --address.street -> "address.street"
144
+ const result = parseDotNotationFlags({
145
+ name: "Ada",
146
+ "address.street": "123 Main",
147
+ "address.city": "NYC",
148
+ }, flagDefs);
149
+ expect(result).toEqual({
150
+ name: "Ada",
151
+ address: {
152
+ street: "123 Main",
153
+ city: "NYC",
154
+ },
155
+ });
156
+ });
157
+ test("handles boolean flags", () => {
158
+ const flagDefs = generateBodyFlags({
159
+ type: "object",
160
+ properties: {
161
+ active: { type: "boolean" },
162
+ },
163
+ }, new Set());
164
+ const result = parseDotNotationFlags({ active: true }, flagDefs);
165
+ expect(result).toEqual({ active: true });
166
+ });
167
+ });
168
+ describe("findMissingRequired", () => {
169
+ test("finds missing required fields", () => {
170
+ const flagDefs = generateBodyFlags({
171
+ type: "object",
172
+ properties: {
173
+ name: { type: "string" },
174
+ email: { type: "string" },
175
+ },
176
+ required: ["name", "email"],
177
+ }, new Set());
178
+ const missing = findMissingRequired({ name: "Ada" }, flagDefs);
179
+ expect(missing).toEqual(["email"]);
180
+ });
181
+ test("returns empty when all required fields present", () => {
182
+ const flagDefs = generateBodyFlags({
183
+ type: "object",
184
+ properties: {
185
+ name: { type: "string" },
186
+ },
187
+ required: ["name"],
188
+ }, new Set());
189
+ const missing = findMissingRequired({ name: "Ada" }, flagDefs);
190
+ expect(missing).toEqual([]);
191
+ });
192
+ });
@@ -12,4 +12,3 @@ export declare function loadBody(input: BodyInput): Promise<{
12
12
  json?: unknown;
13
13
  } | undefined>;
14
14
  export declare function parseBodyAsJsonOrYaml(text: string): unknown;
15
- //# sourceMappingURL=body.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { parseYamlContent, readFileText } from "./compat.js";
2
+ export async function loadBody(input) {
3
+ if (input.kind === "none")
4
+ return undefined;
5
+ if (input.kind === "data")
6
+ return { raw: input.data };
7
+ const text = await readFileText(input.path);
8
+ return { raw: text };
9
+ }
10
+ export function parseBodyAsJsonOrYaml(text) {
11
+ const trimmed = text.trimStart();
12
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
13
+ return JSON.parse(text);
14
+ }
15
+ return parseYamlContent(text);
16
+ }
@@ -1,2 +1 @@
1
1
  export declare function collectRepeatable(value: string, previous: string[] | undefined): string[];
2
- //# sourceMappingURL=collect.d.ts.map
@@ -0,0 +1,3 @@
1
+ export function collectRepeatable(value, previous) {
2
+ return [...(previous ?? []), value];
3
+ }
@@ -32,4 +32,3 @@ export declare function parseYamlContent(text: string): unknown;
32
32
  * Read from stdin - works in both Bun and Node.js
33
33
  */
34
34
  export declare function readStdinText(): Promise<string>;
35
- //# sourceMappingURL=compat.d.ts.map
@@ -0,0 +1,78 @@
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
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
8
+ import { parse as parseYaml } from "yaml";
9
+ /**
10
+ * Detect if we're running in Bun
11
+ */
12
+ export const isBun = typeof globalThis.Bun !== "undefined";
13
+ /**
14
+ * Read a file's text content - works in both Bun and Node.js
15
+ */
16
+ export async function readFileText(path) {
17
+ if (isBun) {
18
+ return Bun.file(path).text();
19
+ }
20
+ return readFileSync(path, "utf-8");
21
+ }
22
+ /**
23
+ * Check if a file exists - works in both Bun and Node.js
24
+ */
25
+ export async function fileExists(path) {
26
+ if (isBun) {
27
+ return Bun.file(path).exists();
28
+ }
29
+ return existsSync(path);
30
+ }
31
+ /**
32
+ * Write text to a file - works in both Bun and Node.js
33
+ */
34
+ export async function writeFileText(path, content) {
35
+ if (isBun) {
36
+ await Bun.write(path, content);
37
+ return;
38
+ }
39
+ writeFileSync(path, content, "utf-8");
40
+ }
41
+ /**
42
+ * Create directory recursively - works in both Bun and Node.js
43
+ */
44
+ export async function mkdirp(path) {
45
+ if (isBun) {
46
+ await Bun.$ `mkdir -p ${path}`;
47
+ return;
48
+ }
49
+ mkdirSync(path, { recursive: true });
50
+ }
51
+ /**
52
+ * Parse YAML content - works in both Bun and Node.js
53
+ */
54
+ export function parseYamlContent(text) {
55
+ if (isBun) {
56
+ const { YAML } = globalThis.Bun;
57
+ return YAML.parse(text);
58
+ }
59
+ return parseYaml(text);
60
+ }
61
+ /**
62
+ * Read from stdin - works in both Bun and Node.js
63
+ */
64
+ export async function readStdinText() {
65
+ if (isBun) {
66
+ return Bun.stdin.text();
67
+ }
68
+ // Node.js stdin reading
69
+ return new Promise((resolve, reject) => {
70
+ let data = "";
71
+ process.stdin.setEncoding("utf8");
72
+ process.stdin.on("data", (chunk) => {
73
+ data += chunk;
74
+ });
75
+ process.stdin.on("end", () => resolve(data));
76
+ process.stdin.on("error", reject);
77
+ });
78
+ }
@@ -13,4 +13,3 @@ export declare function buildRuntimeContext(options: BuildRuntimeContextOptions)
13
13
  capabilities: import("../capabilities.js").Capabilities;
14
14
  schema: import("../schema.js").SchemaOutput;
15
15
  }>;
16
- //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1,44 @@
1
+ import { listAuthSchemes } from "../auth-schemes.js";
2
+ import { deriveCapabilities } from "../capabilities.js";
3
+ import { buildCommandsIndex } from "../command-index.js";
4
+ import { buildCommandModel } from "../command-model.js";
5
+ import { planOperations } from "../naming.js";
6
+ import { indexOperations } from "../operations.js";
7
+ import { buildSchemaOutput } from "../schema.js";
8
+ import { listServers } from "../server.js";
9
+ import { loadSpec } from "../spec-loader.js";
10
+ export async function buildRuntimeContext(options) {
11
+ const loaded = await loadSpec({
12
+ spec: options.spec,
13
+ embeddedSpecText: options.embeddedSpecText,
14
+ });
15
+ const operations = indexOperations(loaded.doc);
16
+ const servers = listServers(loaded.doc);
17
+ const authSchemes = listAuthSchemes(loaded.doc);
18
+ const planned = planOperations(operations);
19
+ const commands = buildCommandModel(planned, {
20
+ specId: loaded.id,
21
+ globalSecurity: loaded.doc.security,
22
+ authSchemes,
23
+ });
24
+ const commandsIndex = buildCommandsIndex(commands);
25
+ const capabilities = deriveCapabilities({
26
+ doc: loaded.doc,
27
+ servers,
28
+ authSchemes,
29
+ operations,
30
+ commands,
31
+ });
32
+ const schema = buildSchemaOutput(loaded, operations, planned, servers, authSchemes, commands, commandsIndex, capabilities);
33
+ return {
34
+ loaded,
35
+ operations,
36
+ servers,
37
+ authSchemes,
38
+ planned,
39
+ commands,
40
+ commandsIndex,
41
+ capabilities,
42
+ schema,
43
+ };
44
+ }
@@ -30,4 +30,3 @@ export declare function execute(input: Omit<ExecuteInput, "resourceName">): Prom
30
30
  * This is the CLI-facing wrapper around execute().
31
31
  */
32
32
  export declare function executeAction(input: ExecuteInput): Promise<void>;
33
- //# sourceMappingURL=execute.d.ts.map