@seamapi/cli 0.18.1 → 0.19.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 (364) hide show
  1. package/README.md +55 -1
  2. package/bin/cli.js +73 -249
  3. package/bin/cli.js.map +1 -1
  4. package/lib/args/coerce.d.ts +28 -0
  5. package/lib/args/coerce.js +131 -0
  6. package/lib/args/coerce.js.map +1 -0
  7. package/lib/{util/cli-args.d.ts → args/parse.d.ts} +12 -15
  8. package/lib/{util/cli-args.js → args/parse.js} +21 -24
  9. package/lib/args/parse.js.map +1 -0
  10. package/lib/args/validate.d.ts +23 -0
  11. package/lib/args/validate.js +42 -0
  12. package/lib/args/validate.js.map +1 -0
  13. package/lib/auth/operations.d.ts +54 -0
  14. package/lib/auth/operations.js +115 -0
  15. package/lib/auth/operations.js.map +1 -0
  16. package/lib/{validate-token.js → auth/validate-token.js} +2 -2
  17. package/lib/auth/validate-token.js.map +1 -0
  18. package/lib/blueprint/cache.d.ts +16 -0
  19. package/lib/blueprint/cache.js +73 -0
  20. package/lib/blueprint/cache.js.map +1 -0
  21. package/lib/blueprint/endpoint.d.ts +14 -0
  22. package/lib/{get-response-key.js → blueprint/endpoint.js} +11 -2
  23. package/lib/blueprint/endpoint.js.map +1 -0
  24. package/lib/blueprint/index.d.ts +12 -0
  25. package/lib/blueprint/index.js +10 -0
  26. package/lib/blueprint/index.js.map +1 -0
  27. package/lib/blueprint/source-npm.d.ts +10 -0
  28. package/lib/{blueprint.js → blueprint/source-npm.js} +20 -74
  29. package/lib/blueprint/source-npm.js.map +1 -0
  30. package/lib/blueprint/source-remote.d.ts +6 -0
  31. package/lib/blueprint/source-remote.js +14 -0
  32. package/lib/blueprint/source-remote.js.map +1 -0
  33. package/lib/commands/api-command.d.ts +8 -0
  34. package/lib/commands/api-command.js +71 -0
  35. package/lib/commands/api-command.js.map +1 -0
  36. package/lib/commands/local/completion.d.ts +18 -0
  37. package/lib/commands/local/completion.js +35 -0
  38. package/lib/commands/local/completion.js.map +1 -0
  39. package/lib/commands/local/config-reveal-location.d.ts +2 -0
  40. package/lib/commands/local/config-reveal-location.js +15 -0
  41. package/lib/commands/local/config-reveal-location.js.map +1 -0
  42. package/lib/commands/local/config-set-fake-server.d.ts +3 -0
  43. package/lib/commands/local/config-set-fake-server.js +20 -0
  44. package/lib/commands/local/config-set-fake-server.js.map +1 -0
  45. package/lib/commands/local/config-use-remote-api-defs.d.ts +2 -0
  46. package/lib/commands/local/config-use-remote-api-defs.js +20 -0
  47. package/lib/commands/local/config-use-remote-api-defs.js.map +1 -0
  48. package/lib/commands/local/health.d.ts +2 -0
  49. package/lib/commands/local/health.js +18 -0
  50. package/lib/commands/local/health.js.map +1 -0
  51. package/lib/commands/local/login.d.ts +2 -0
  52. package/lib/commands/local/login.js +35 -0
  53. package/lib/commands/local/login.js.map +1 -0
  54. package/lib/commands/local/logout.d.ts +2 -0
  55. package/lib/commands/local/logout.js +17 -0
  56. package/lib/commands/local/logout.js.map +1 -0
  57. package/lib/commands/local/select-server.d.ts +2 -0
  58. package/lib/commands/local/select-server.js +27 -0
  59. package/lib/commands/local/select-server.js.map +1 -0
  60. package/lib/commands/local/select-workspace.d.ts +2 -0
  61. package/lib/commands/local/select-workspace.js +22 -0
  62. package/lib/commands/local/select-workspace.js.map +1 -0
  63. package/lib/commands/local/wizard.d.ts +9 -0
  64. package/lib/commands/local/wizard.js +28 -0
  65. package/lib/commands/local/wizard.js.map +1 -0
  66. package/lib/commands/registry.d.ts +54 -0
  67. package/lib/commands/registry.js +64 -0
  68. package/lib/commands/registry.js.map +1 -0
  69. package/lib/{command-spec.d.ts → commands/spec.d.ts} +8 -12
  70. package/lib/{command-spec.js → commands/spec.js} +27 -120
  71. package/lib/commands/spec.js.map +1 -0
  72. package/lib/config/config-store.d.ts +23 -8
  73. package/lib/config/config-store.js +16 -42
  74. package/lib/config/config-store.js.map +1 -1
  75. package/lib/config/index.d.ts +2 -1
  76. package/lib/config/index.js +2 -1
  77. package/lib/config/index.js.map +1 -1
  78. package/lib/config/memory-config-store.d.ts +21 -0
  79. package/lib/config/memory-config-store.js +48 -0
  80. package/lib/config/memory-config-store.js.map +1 -0
  81. package/lib/config/migrate.js +1 -1
  82. package/lib/config/migrate.js.map +1 -1
  83. package/lib/config/values.d.ts +12 -0
  84. package/lib/config/values.js +50 -0
  85. package/lib/config/values.js.map +1 -0
  86. package/lib/context.d.ts +37 -0
  87. package/lib/context.js +31 -0
  88. package/lib/context.js.map +1 -0
  89. package/lib/env.d.ts +5 -0
  90. package/lib/env.js +5 -0
  91. package/lib/env.js.map +1 -1
  92. package/lib/errors.d.ts +31 -0
  93. package/lib/errors.js +58 -0
  94. package/lib/errors.js.map +1 -0
  95. package/lib/http/api.d.ts +37 -0
  96. package/lib/http/api.js +20 -0
  97. package/lib/http/api.js.map +1 -0
  98. package/lib/http/client.d.ts +4 -0
  99. package/lib/{get-seam.js → http/client.js} +16 -17
  100. package/lib/http/client.js.map +1 -0
  101. package/lib/http/follow-ups.d.ts +6 -0
  102. package/lib/http/follow-ups.js +30 -0
  103. package/lib/http/follow-ups.js.map +1 -0
  104. package/lib/http/memory-seam-api.d.ts +22 -0
  105. package/lib/http/memory-seam-api.js +41 -0
  106. package/lib/http/memory-seam-api.js.map +1 -0
  107. package/lib/http/request.d.ts +19 -0
  108. package/lib/http/request.js +39 -0
  109. package/lib/http/request.js.map +1 -0
  110. package/lib/{interact-for-access-code.js → interactions/access-code.js} +4 -4
  111. package/lib/interactions/access-code.js.map +1 -0
  112. package/lib/{interact-for-acs-entrance.js → interactions/acs-entrance.js} +3 -3
  113. package/lib/interactions/acs-entrance.js.map +1 -0
  114. package/lib/{interact-for-acs-system.js → interactions/acs-system.js} +3 -3
  115. package/lib/interactions/acs-system.js.map +1 -0
  116. package/lib/{interact-for-acs-user.js → interactions/acs-user.js} +4 -4
  117. package/lib/interactions/acs-user.js.map +1 -0
  118. package/lib/{interact-for-action-attempt-poll.js → interactions/action-attempt-poll.js} +5 -5
  119. package/lib/interactions/action-attempt-poll.js.map +1 -0
  120. package/lib/{interact-for-array.js → interactions/array.js} +4 -3
  121. package/lib/interactions/array.js.map +1 -0
  122. package/lib/{interact-for-blueprint-object.d.ts → interactions/blueprint-object.d.ts} +3 -2
  123. package/lib/{interact-for-blueprint-object.js → interactions/blueprint-object.js} +49 -20
  124. package/lib/interactions/blueprint-object.js.map +1 -0
  125. package/lib/{interact-for-command-params.d.ts → interactions/command-params.d.ts} +2 -2
  126. package/lib/{interact-for-command-params.js → interactions/command-params.js} +4 -3
  127. package/lib/interactions/command-params.js.map +1 -0
  128. package/lib/interactions/command-selection.d.ts +10 -0
  129. package/lib/{interact-for-command-selection.js → interactions/command-selection.js} +9 -15
  130. package/lib/interactions/command-selection.js.map +1 -0
  131. package/lib/{interact-for-connected-account.js → interactions/connected-account.js} +3 -3
  132. package/lib/interactions/connected-account.js.map +1 -0
  133. package/lib/{interact-for-custom-metadata.js → interactions/custom-metadata.js} +4 -3
  134. package/lib/interactions/custom-metadata.js.map +1 -0
  135. package/lib/{interact-for-device.js → interactions/device.js} +3 -3
  136. package/lib/interactions/device.js.map +1 -0
  137. package/lib/interactions/index.d.ts +19 -0
  138. package/lib/interactions/index.js +20 -0
  139. package/lib/interactions/index.js.map +1 -0
  140. package/lib/{interact-for-login.js → interactions/login.js} +16 -14
  141. package/lib/interactions/login.js.map +1 -0
  142. package/lib/{interact-for-resource.js → interactions/resource.js} +3 -3
  143. package/lib/interactions/resource.js.map +1 -0
  144. package/lib/{interact-for-server-selection.js → interactions/server-selection.js} +10 -13
  145. package/lib/interactions/server-selection.js.map +1 -0
  146. package/lib/{interact-for-timestamp.js → interactions/timestamp.js} +2 -2
  147. package/lib/interactions/timestamp.js.map +1 -0
  148. package/lib/{interact-for-use-remote-api-defs.js → interactions/use-remote-api-defs.js} +5 -6
  149. package/lib/interactions/use-remote-api-defs.js.map +1 -0
  150. package/lib/{interact-for-user-identity.js → interactions/user-identity.js} +3 -3
  151. package/lib/interactions/user-identity.js.map +1 -0
  152. package/lib/{interact-for-workspace-id.js → interactions/workspace-id.js} +11 -10
  153. package/lib/interactions/workspace-id.js.map +1 -0
  154. package/lib/memory-prompt.d.ts +32 -0
  155. package/lib/memory-prompt.js +41 -0
  156. package/lib/memory-prompt.js.map +1 -0
  157. package/lib/output/get-output.d.ts +1 -1
  158. package/lib/output/get-output.js +1 -1
  159. package/lib/output/get-output.js.map +1 -1
  160. package/lib/output/{create-memory-output.d.ts → memory-output.d.ts} +1 -1
  161. package/lib/output/{create-memory-output.js → memory-output.js} +2 -2
  162. package/lib/output/memory-output.js.map +1 -0
  163. package/lib/output/{create-output.d.ts → output.d.ts} +18 -1
  164. package/lib/output/output.js +46 -0
  165. package/lib/output/output.js.map +1 -0
  166. package/lib/output/read-stdin-json.js.map +1 -0
  167. package/lib/output/resolve-output-format.d.ts +1 -1
  168. package/lib/{util → output}/with-loading.js +1 -1
  169. package/lib/output/with-loading.js.map +1 -0
  170. package/lib/prompt.d.ts +101 -0
  171. package/lib/{util/prompt.js → prompt.js} +83 -56
  172. package/lib/prompt.js.map +1 -0
  173. package/lib/{completion → render/completion}/describe.js +1 -2
  174. package/lib/render/completion/describe.js.map +1 -0
  175. package/lib/{completion → render/completion}/index.d.ts +2 -2
  176. package/lib/{completion → render/completion}/index.js +1 -2
  177. package/lib/render/completion/index.js.map +1 -0
  178. package/lib/{completion → render/completion}/render-bash.d.ts +1 -1
  179. package/lib/{completion → render/completion}/render-bash.js +1 -1
  180. package/lib/render/completion/render-bash.js.map +1 -0
  181. package/lib/{completion → render/completion}/render-fish.d.ts +1 -1
  182. package/lib/render/completion/render-fish.js.map +1 -0
  183. package/lib/{completion → render/completion}/render-zsh.d.ts +1 -1
  184. package/lib/{completion → render/completion}/render-zsh.js +1 -1
  185. package/lib/render/completion/render-zsh.js.map +1 -0
  186. package/lib/{render-help.d.ts → render/help.d.ts} +1 -1
  187. package/lib/{render-help.js → render/help.js} +2 -2
  188. package/lib/render/help.js.map +1 -0
  189. package/lib/render/text.d.ts +4 -0
  190. package/lib/render/text.js +16 -0
  191. package/lib/render/text.js.map +1 -0
  192. package/lib/version.d.ts +2 -2
  193. package/lib/version.js +2 -2
  194. package/package.json +4 -3
  195. package/src/bin/cli.ts +91 -332
  196. package/src/lib/args/coerce.ts +164 -0
  197. package/src/lib/{util/cli-args.ts → args/parse.ts} +30 -25
  198. package/src/lib/args/validate.ts +73 -0
  199. package/src/lib/auth/operations.ts +169 -0
  200. package/src/lib/{validate-token.ts → auth/validate-token.ts} +2 -2
  201. package/src/lib/blueprint/cache.ts +97 -0
  202. package/src/lib/{get-response-key.ts → blueprint/endpoint.ts} +17 -3
  203. package/src/lib/blueprint/index.ts +27 -0
  204. package/src/lib/{blueprint.ts → blueprint/source-npm.ts} +27 -99
  205. package/src/lib/blueprint/source-remote.ts +17 -0
  206. package/src/lib/commands/api-command.ts +109 -0
  207. package/src/lib/commands/local/completion.ts +51 -0
  208. package/src/lib/commands/local/config-reveal-location.ts +16 -0
  209. package/src/lib/commands/local/config-set-fake-server.ts +21 -0
  210. package/src/lib/commands/local/config-use-remote-api-defs.ts +23 -0
  211. package/src/lib/commands/local/health.ts +22 -0
  212. package/src/lib/commands/local/login.ts +42 -0
  213. package/src/lib/commands/local/logout.ts +18 -0
  214. package/src/lib/commands/local/select-server.ts +30 -0
  215. package/src/lib/commands/local/select-workspace.ts +25 -0
  216. package/src/lib/commands/local/wizard.ts +31 -0
  217. package/src/lib/commands/registry.ts +127 -0
  218. package/src/lib/{command-spec.ts → commands/spec.ts} +30 -131
  219. package/src/lib/config/config-store.ts +39 -64
  220. package/src/lib/config/index.ts +8 -1
  221. package/src/lib/config/memory-config-store.ts +62 -0
  222. package/src/lib/config/migrate.ts +1 -1
  223. package/src/lib/config/values.ts +72 -0
  224. package/src/lib/context.ts +84 -0
  225. package/src/lib/env.ts +9 -2
  226. package/src/lib/errors.ts +67 -0
  227. package/src/lib/http/api.ts +61 -0
  228. package/src/lib/{get-seam.ts → http/client.ts} +19 -18
  229. package/src/lib/http/follow-ups.ts +42 -0
  230. package/src/lib/http/memory-seam-api.ts +57 -0
  231. package/src/lib/http/request.ts +69 -0
  232. package/src/lib/{interact-for-access-code.ts → interactions/access-code.ts} +4 -3
  233. package/src/lib/{interact-for-acs-entrance.ts → interactions/acs-entrance.ts} +3 -2
  234. package/src/lib/{interact-for-acs-system.ts → interactions/acs-system.ts} +3 -2
  235. package/src/lib/{interact-for-acs-user.ts → interactions/acs-user.ts} +4 -3
  236. package/src/lib/{interact-for-action-attempt-poll.ts → interactions/action-attempt-poll.ts} +4 -4
  237. package/src/lib/{interact-for-array.ts → interactions/array.ts} +3 -3
  238. package/src/lib/{interact-for-blueprint-object.ts → interactions/blueprint-object.ts} +57 -24
  239. package/src/lib/{interact-for-command-params.ts → interactions/command-params.ts} +6 -4
  240. package/src/lib/{interact-for-command-selection.ts → interactions/command-selection.ts} +11 -23
  241. package/src/lib/{interact-for-connected-account.ts → interactions/connected-account.ts} +3 -2
  242. package/src/lib/{interact-for-custom-metadata.ts → interactions/custom-metadata.ts} +3 -7
  243. package/src/lib/{interact-for-device.ts → interactions/device.ts} +3 -2
  244. package/src/lib/interactions/index.ts +19 -0
  245. package/src/lib/{interact-for-login.ts → interactions/login.ts} +16 -13
  246. package/src/lib/{interact-for-resource.ts → interactions/resource.ts} +2 -2
  247. package/src/lib/{interact-for-server-selection.ts → interactions/server-selection.ts} +12 -17
  248. package/src/lib/{interact-for-timestamp.ts → interactions/timestamp.ts} +1 -1
  249. package/src/lib/{interact-for-use-remote-api-defs.ts → interactions/use-remote-api-defs.ts} +4 -5
  250. package/src/lib/{interact-for-user-identity.ts → interactions/user-identity.ts} +3 -2
  251. package/src/lib/{interact-for-workspace-id.ts → interactions/workspace-id.ts} +10 -17
  252. package/src/lib/memory-prompt.ts +89 -0
  253. package/src/lib/output/get-output.ts +1 -1
  254. package/src/lib/output/{create-memory-output.ts → memory-output.ts} +1 -1
  255. package/src/lib/output/{create-output.ts → output.ts} +47 -32
  256. package/src/lib/output/resolve-output-format.ts +1 -1
  257. package/src/lib/{util → output}/with-loading.ts +1 -1
  258. package/src/lib/prompt.ts +306 -0
  259. package/src/lib/{completion → render/completion}/describe.ts +1 -2
  260. package/src/lib/{completion → render/completion}/index.ts +3 -4
  261. package/src/lib/{completion → render/completion}/render-bash.ts +1 -1
  262. package/src/lib/{completion → render/completion}/render-fish.ts +2 -1
  263. package/src/lib/{completion → render/completion}/render-zsh.ts +2 -1
  264. package/src/lib/{render-help.ts → render/help.ts} +1 -1
  265. package/src/lib/render/text.ts +17 -0
  266. package/src/lib/version.ts +2 -2
  267. package/lib/blueprint.d.ts +0 -7
  268. package/lib/blueprint.js.map +0 -1
  269. package/lib/command-spec.js.map +0 -1
  270. package/lib/completion/describe.js.map +0 -1
  271. package/lib/completion/index.js.map +0 -1
  272. package/lib/completion/render-bash.js.map +0 -1
  273. package/lib/completion/render-fish.js.map +0 -1
  274. package/lib/completion/render-zsh.js.map +0 -1
  275. package/lib/get-api-blueprint.d.ts +0 -6
  276. package/lib/get-api-blueprint.js +0 -18
  277. package/lib/get-api-blueprint.js.map +0 -1
  278. package/lib/get-command-blueprint-def.d.ts +0 -2
  279. package/lib/get-command-blueprint-def.js +0 -11
  280. package/lib/get-command-blueprint-def.js.map +0 -1
  281. package/lib/get-credentials.d.ts +0 -15
  282. package/lib/get-credentials.js +0 -35
  283. package/lib/get-credentials.js.map +0 -1
  284. package/lib/get-current-workspace-id.d.ts +0 -1
  285. package/lib/get-current-workspace-id.js +0 -9
  286. package/lib/get-current-workspace-id.js.map +0 -1
  287. package/lib/get-response-key.d.ts +0 -9
  288. package/lib/get-response-key.js.map +0 -1
  289. package/lib/get-seam.d.ts +0 -3
  290. package/lib/get-seam.js.map +0 -1
  291. package/lib/get-server.d.ts +0 -6
  292. package/lib/get-server.js +0 -17
  293. package/lib/get-server.js.map +0 -1
  294. package/lib/interact-for-access-code.js.map +0 -1
  295. package/lib/interact-for-acs-entrance.js.map +0 -1
  296. package/lib/interact-for-acs-system.js.map +0 -1
  297. package/lib/interact-for-acs-user.js.map +0 -1
  298. package/lib/interact-for-action-attempt-poll.js.map +0 -1
  299. package/lib/interact-for-array.js.map +0 -1
  300. package/lib/interact-for-blueprint-object.js.map +0 -1
  301. package/lib/interact-for-command-params.js.map +0 -1
  302. package/lib/interact-for-command-selection.d.ts +0 -2
  303. package/lib/interact-for-command-selection.js.map +0 -1
  304. package/lib/interact-for-connected-account.js.map +0 -1
  305. package/lib/interact-for-custom-metadata.js.map +0 -1
  306. package/lib/interact-for-device.js.map +0 -1
  307. package/lib/interact-for-login.js.map +0 -1
  308. package/lib/interact-for-resource.js.map +0 -1
  309. package/lib/interact-for-server-selection.js.map +0 -1
  310. package/lib/interact-for-timestamp.js.map +0 -1
  311. package/lib/interact-for-use-remote-api-defs.js.map +0 -1
  312. package/lib/interact-for-user-identity.js.map +0 -1
  313. package/lib/interact-for-workspace-id.js.map +0 -1
  314. package/lib/output/create-memory-output.js.map +0 -1
  315. package/lib/output/create-output.js +0 -34
  316. package/lib/output/create-output.js.map +0 -1
  317. package/lib/render-help.js.map +0 -1
  318. package/lib/types.d.ts +0 -6
  319. package/lib/types.js +0 -2
  320. package/lib/types.js.map +0 -1
  321. package/lib/util/cli-args.js.map +0 -1
  322. package/lib/util/ellipsis.d.ts +0 -1
  323. package/lib/util/ellipsis.js +0 -6
  324. package/lib/util/ellipsis.js.map +0 -1
  325. package/lib/util/prompt.d.ts +0 -80
  326. package/lib/util/prompt.js.map +0 -1
  327. package/lib/util/read-stdin-json.js.map +0 -1
  328. package/lib/util/request-seam-api.d.ts +0 -7
  329. package/lib/util/request-seam-api.js +0 -26
  330. package/lib/util/request-seam-api.js.map +0 -1
  331. package/lib/util/with-loading.js.map +0 -1
  332. package/lib/validate-token.js.map +0 -1
  333. package/src/lib/get-api-blueprint.ts +0 -31
  334. package/src/lib/get-command-blueprint-def.ts +0 -15
  335. package/src/lib/get-credentials.ts +0 -38
  336. package/src/lib/get-current-workspace-id.ts +0 -9
  337. package/src/lib/get-server.ts +0 -20
  338. package/src/lib/types.ts +0 -7
  339. package/src/lib/util/ellipsis.ts +0 -4
  340. package/src/lib/util/prompt.ts +0 -229
  341. package/src/lib/util/request-seam-api.ts +0 -47
  342. /package/lib/{validate-token.d.ts → auth/validate-token.d.ts} +0 -0
  343. /package/lib/{interact-for-access-code.d.ts → interactions/access-code.d.ts} +0 -0
  344. /package/lib/{interact-for-acs-entrance.d.ts → interactions/acs-entrance.d.ts} +0 -0
  345. /package/lib/{interact-for-acs-system.d.ts → interactions/acs-system.d.ts} +0 -0
  346. /package/lib/{interact-for-acs-user.d.ts → interactions/acs-user.d.ts} +0 -0
  347. /package/lib/{interact-for-action-attempt-poll.d.ts → interactions/action-attempt-poll.d.ts} +0 -0
  348. /package/lib/{interact-for-array.d.ts → interactions/array.d.ts} +0 -0
  349. /package/lib/{interact-for-connected-account.d.ts → interactions/connected-account.d.ts} +0 -0
  350. /package/lib/{interact-for-custom-metadata.d.ts → interactions/custom-metadata.d.ts} +0 -0
  351. /package/lib/{interact-for-device.d.ts → interactions/device.d.ts} +0 -0
  352. /package/lib/{interact-for-login.d.ts → interactions/login.d.ts} +0 -0
  353. /package/lib/{interact-for-resource.d.ts → interactions/resource.d.ts} +0 -0
  354. /package/lib/{interact-for-server-selection.d.ts → interactions/server-selection.d.ts} +0 -0
  355. /package/lib/{interact-for-timestamp.d.ts → interactions/timestamp.d.ts} +0 -0
  356. /package/lib/{interact-for-use-remote-api-defs.d.ts → interactions/use-remote-api-defs.d.ts} +0 -0
  357. /package/lib/{interact-for-user-identity.d.ts → interactions/user-identity.d.ts} +0 -0
  358. /package/lib/{interact-for-workspace-id.d.ts → interactions/workspace-id.d.ts} +0 -0
  359. /package/lib/{util → output}/read-stdin-json.d.ts +0 -0
  360. /package/lib/{util → output}/read-stdin-json.js +0 -0
  361. /package/lib/{util → output}/with-loading.d.ts +0 -0
  362. /package/lib/{completion → render/completion}/describe.d.ts +0 -0
  363. /package/lib/{completion → render/completion}/render-fish.js +0 -0
  364. /package/src/lib/{util → output}/read-stdin-json.ts +0 -0
@@ -0,0 +1,127 @@
1
+ import type { ParsedArgs } from 'minimist'
2
+
3
+ import { toParameterName } from 'lib/args/parse.js'
4
+ import type { ApiBlueprint } from 'lib/blueprint/index.js'
5
+ import type { CliContext } from 'lib/context.js'
6
+
7
+ import { executeApiCommand } from './api-command.js'
8
+ import { createCompletionCommands } from './local/completion.js'
9
+ import { configRevealLocationCommand } from './local/config-reveal-location.js'
10
+ import { configSetFakeServerCommand } from './local/config-set-fake-server.js'
11
+ import { configUseRemoteApiDefsCommand } from './local/config-use-remote-api-defs.js'
12
+ import { healthCommand } from './local/health.js'
13
+ import { loginCommand } from './local/login.js'
14
+ import { logoutCommand } from './local/logout.js'
15
+ import { selectServerCommand } from './local/select-server.js'
16
+ import { selectWorkspaceCommand } from './local/select-workspace.js'
17
+ import { wizardCommand } from './local/wizard.js'
18
+ import {
19
+ type CommandDefinition,
20
+ type CommandSpec,
21
+ getCommandSpec,
22
+ isSamePath,
23
+ } from './spec.js'
24
+
25
+ /**
26
+ * One invocable command: what it looks like to help, completion, and the
27
+ * interactive picker, whether it needs a login, and how to run it. Declaring
28
+ * the metadata and the executor together is what keeps them from drifting.
29
+ */
30
+ export interface Command {
31
+ definition: CommandDefinition
32
+ /** Whether the command needs a token before it can do anything. */
33
+ requiresAuth: boolean
34
+ /** Kept out of the spec, so out of help, completion, and the picker. */
35
+ hidden?: boolean
36
+ execute: (invocation: Invocation, ctx: CliContext) => Promise<CommandResult>
37
+ }
38
+
39
+ /** Everything a single run of a command was given. */
40
+ export interface Invocation {
41
+ path: string[]
42
+ /** Params given as arguments, held to what the command accepts. */
43
+ argParams: Record<string, unknown>
44
+ /** Params piped in as JSON, passed through as given. */
45
+ stdinParams: Record<string, unknown>
46
+ /** The full parsed arguments, for commands that read their own flags. */
47
+ args: ParsedArgs
48
+ /** The raw argv, for commands that re-read arguments with their own types. */
49
+ argv: string[]
50
+ }
51
+
52
+ export type CommandResult =
53
+ | { kind: 'done' }
54
+ /** Navigate back to selecting a command under `toPath`. */
55
+ | { kind: 'back'; toPath: string[] }
56
+
57
+ export interface CommandRegistry {
58
+ /** The spec help, completion, and the interactive picker render. */
59
+ spec: CommandSpec
60
+ find: (path: string[]) => Command | undefined
61
+ }
62
+
63
+ /**
64
+ * Commands handled by the CLI itself, which have no endpoint in the
65
+ * blueprint. The single source of truth: the spec, the picker, and the
66
+ * dispatcher all consume this list.
67
+ */
68
+ const completionCommands = createCompletionCommands(
69
+ (blueprint) => buildRegistry(blueprint).spec,
70
+ )
71
+
72
+ export const localCommands: Command[] = [
73
+ ...completionCommands,
74
+ configRevealLocationCommand,
75
+ configSetFakeServerCommand,
76
+ configUseRemoteApiDefsCommand,
77
+ healthCommand,
78
+ loginCommand,
79
+ logoutCommand,
80
+ selectServerCommand,
81
+ selectWorkspaceCommand,
82
+ wizardCommand,
83
+ ]
84
+
85
+ /** Definitions shown in help, completion, and the picker. */
86
+ export const localCommandDefinitions: CommandDefinition[] = localCommands
87
+ .filter((command) => command.hidden !== true)
88
+ .map((command) => command.definition)
89
+
90
+ /**
91
+ * The local command going by a path, or `undefined` when the path is an
92
+ * endpoint or no command at all. Needs no blueprint, so the entry may check
93
+ * commands before any definitions are loaded.
94
+ */
95
+ export const findLocalCommand = (path: string[]): Command | undefined =>
96
+ localCommands.find((command) => isSamePath(command.definition.path, path))
97
+
98
+ /** Parameter names a command accepts as arguments. */
99
+ export const acceptedParamsOf = (definition: CommandDefinition): Set<string> =>
100
+ new Set(
101
+ definition.flags.flatMap(({ long }) =>
102
+ long == null ? [] : [toParameterName(long)],
103
+ ),
104
+ )
105
+
106
+ export const buildRegistry = (blueprint: ApiBlueprint): CommandRegistry => {
107
+ const spec = getCommandSpec(blueprint, localCommandDefinitions)
108
+
109
+ const commands = new Map<string, Command>()
110
+ for (const definition of spec.commands) {
111
+ commands.set(definition.path.join(' '), {
112
+ definition,
113
+ requiresAuth: true,
114
+ execute: executeApiCommand,
115
+ })
116
+ }
117
+ // Local commands win over a same-named endpoint, as the spec's dedupe does,
118
+ // and hidden ones are findable without being in the spec.
119
+ for (const command of localCommands) {
120
+ commands.set(command.definition.path.join(' '), command)
121
+ }
122
+
123
+ return {
124
+ spec,
125
+ find: (path) => commands.get(path.join(' ')),
126
+ }
127
+ }
@@ -1,5 +1,7 @@
1
1
  import type { Blueprint } from '@seamapi/blueprint'
2
2
 
3
+ import { firstSentence, toPlainText } from 'lib/render/text.js'
4
+
3
5
  type Endpoint = Blueprint['routes'][number]['endpoints'][number]
4
6
  type Parameter = Endpoint['request']['parameters'][number]
5
7
 
@@ -122,7 +124,15 @@ export const flagTokens = (flag: CommandFlag): string[] => {
122
124
  return tokens
123
125
  }
124
126
 
125
- export const getCommandSpec = (blueprint: Blueprint): CommandSpec => {
127
+ /**
128
+ * Derive the command spec from the API definitions, merged with the commands
129
+ * the CLI declares itself (see `commands/registry.ts`, the single source of
130
+ * those declarations).
131
+ */
132
+ export const getCommandSpec = (
133
+ blueprint: Blueprint,
134
+ localCommands: CommandDefinition[] = [],
135
+ ): CommandSpec => {
126
136
  const commands = sortByPath(
127
137
  dedupeByPath([
128
138
  ...blueprint.routes
@@ -151,22 +161,10 @@ export const findGroup = (
151
161
  ): CommandGroup | undefined =>
152
162
  spec.groups.find((group) => isSamePath(group.path, path))
153
163
 
154
- /**
155
- * The definition of a command the CLI handles itself, or `undefined` when the
156
- * path is an endpoint or no command at all.
157
- *
158
- * Unlike {@link findCommand} this needs no blueprint, since these commands are
159
- * declared by the CLI rather than derived from the API definitions.
160
- */
161
- export const findLocalCommand = (
162
- path: string[],
163
- ): CommandDefinition | undefined =>
164
- localCommands.find((command) => isSamePath(command.path, path))
165
-
166
- const isSamePath = (a: string[], b: string[]): boolean =>
164
+ export const isSamePath = (a: string[], b: string[]): boolean =>
167
165
  a.length === b.length && a.every((word, index) => word === b[index])
168
166
 
169
- const stringFlag = (long: string, description: string): CommandFlag => ({
167
+ export const stringFlag = (long: string, description: string): CommandFlag => ({
170
168
  long,
171
169
  short: null,
172
170
  description,
@@ -175,98 +173,6 @@ const stringFlag = (long: string, description: string): CommandFlag => ({
175
173
  isRequired: false,
176
174
  })
177
175
 
178
- /**
179
- * Commands handled by the CLI itself, which have no endpoint in the blueprint.
180
- *
181
- * Keep in sync with the command handling in `src/bin/cli.ts` and the extra
182
- * commands offered by `interactForCommandSelection`.
183
- */
184
- const localCommands: CommandDefinition[] = [
185
- {
186
- path: ['completion', 'bash'],
187
- kind: 'cli',
188
- title: 'Print the bash completion script.',
189
- description: '',
190
- flags: [],
191
- },
192
- {
193
- path: ['completion', 'fish'],
194
- kind: 'cli',
195
- title: 'Print the fish completion script.',
196
- description: '',
197
- flags: [],
198
- },
199
- {
200
- path: ['completion', 'zsh'],
201
- kind: 'cli',
202
- title: 'Print the zsh completion script.',
203
- description: '',
204
- flags: [],
205
- },
206
- {
207
- path: ['config', 'reveal-location'],
208
- kind: 'cli',
209
- title: 'Print the path to the CLI configuration file.',
210
- description: '',
211
- flags: [],
212
- },
213
- {
214
- path: ['config', 'use-remote-api-defs'],
215
- kind: 'cli',
216
- title: 'Choose whether to use the API definitions served by Seam.',
217
- description: '',
218
- flags: [],
219
- },
220
- {
221
- path: ['health', 'get-health'],
222
- kind: 'api',
223
- title: 'Report the health of the Seam API.',
224
- description: '',
225
- flags: [],
226
- },
227
- {
228
- path: ['login'],
229
- kind: 'cli',
230
- title: 'Log in to Seam.',
231
- description:
232
- 'Prompts for a personal access token unless one is passed with --token.',
233
- flags: [
234
- stringFlag('server', 'Seam API server to log in to.'),
235
- stringFlag('token', 'Personal access token to log in with.'),
236
- stringFlag('workspace-id', 'Workspace to select after logging in.'),
237
- ],
238
- },
239
- {
240
- path: ['logout'],
241
- kind: 'cli',
242
- title: 'Log out of Seam.',
243
- description: '',
244
- flags: [],
245
- },
246
- {
247
- path: ['select', 'server'],
248
- kind: 'cli',
249
- title: 'Select the Seam API server.',
250
- description: '',
251
- flags: [stringFlag('server', 'Seam API server to select.')],
252
- },
253
- {
254
- path: ['select', 'workspace'],
255
- kind: 'cli',
256
- title: 'Select the current workspace.',
257
- description: '',
258
- flags: [],
259
- },
260
- {
261
- path: ['wizard'],
262
- kind: 'cli',
263
- title: 'Set up Seam in the current project.',
264
- description:
265
- 'Takes a project from zero to a working Seam integration. Run seam wizard --help for its own options.',
266
- flags: [],
267
- },
268
- ]
269
-
270
176
  const toCommandDefinition = (endpoint: Endpoint): CommandDefinition => {
271
177
  const description = toPlainText(endpoint.description)
272
178
 
@@ -295,19 +201,21 @@ const toCommandFlag = (parameter: Parameter): CommandFlag => ({
295
201
  })
296
202
 
297
203
  const toFlagValues = (parameter: Parameter): string[] => {
298
- if (parameter.format === 'enum') {
299
- return parameter.values.map(({ name }) => name).filter(isSafeToken)
300
- }
204
+ let values: string[] = []
301
205
 
302
- if (parameter.format === 'list' && parameter.itemFormat === 'enum') {
303
- return parameter.itemEnumValues.map(({ name }) => name).filter(isSafeToken)
206
+ if (parameter.format === 'enum') {
207
+ values = parameter.values.map(({ name }) => name).filter(isSafeToken)
208
+ } else if (parameter.format === 'list' && parameter.itemFormat === 'enum') {
209
+ values = parameter.itemEnumValues
210
+ .map(({ name }) => name)
211
+ .filter(isSafeToken)
212
+ } else if (parameter.format === 'boolean') {
213
+ // Nothing marks parameters as boolean-only flags, so minimist reads the
214
+ // next argument as the value.
215
+ values = ['true', 'false']
304
216
  }
305
217
 
306
- // Nothing marks parameters as boolean-only flags, so minimist reads the next
307
- // argument as the value.
308
- if (parameter.format === 'boolean') return ['true', 'false']
309
-
310
- return []
218
+ return parameter.isNullable ? [...values, 'null'] : values
311
219
  }
312
220
 
313
221
  /**
@@ -342,7 +250,11 @@ const toCommandGroups = (commands: CommandDefinition[]): CommandGroup[] => {
342
250
  // `seam devices` alongside `seam devices list`. Prefer the command
343
251
  // title, since it describes what running the name does.
344
252
  if (depth === command.path.length - 1) {
345
- entries.set(name, { isCommand: true, kind, description: command.title })
253
+ entries.set(name, {
254
+ isCommand: true,
255
+ kind,
256
+ description: command.title,
257
+ })
346
258
  continue
347
259
  }
348
260
 
@@ -397,16 +309,3 @@ const toCommandPath = (path: string): string[] =>
397
309
  path.replace(/^\//, '').split('/').map(toFlagName)
398
310
 
399
311
  const toFlagName = (name: string): string => name.replace(/_/g, '-')
400
-
401
- /** Reduce documentation markdown to a single line of prose. */
402
- export const toPlainText = (markdown: string): string =>
403
- markdown
404
- .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
405
- .replace(/[`*]/g, '')
406
- .replace(/\s+/g, ' ')
407
- .trim()
408
-
409
- export const firstSentence = (text: string): string => {
410
- const [sentence] = text.split(/(?<=\.)\s/)
411
- return sentence ?? text
412
- }
@@ -4,14 +4,48 @@ import Configstore from 'configstore'
4
4
  import envPaths from 'env-paths'
5
5
 
6
6
  import { migrateConfigStore } from './migrate.js'
7
+ import { isStateKey, mergeConfig, splitConfig } from './values.js'
7
8
 
8
9
  const configFileName = 'cli.json'
9
10
  const legacyConfigStoreId = 'seam-cli'
10
- const currentWorkspaceIdKey = 'current_workspace_id'
11
- const patKey = 'pat'
12
11
  const paths = envPaths('seam', { suffix: '' })
13
12
 
14
- export const getConfigStore = () => {
13
+ /**
14
+ * What a config store can do, regardless of where it keeps the values.
15
+ *
16
+ * The CLI reads and writes through this interface so a test may hand code an
17
+ * in-memory store (see `memory-config-store.ts`) instead of the real
18
+ * file-backed one.
19
+ */
20
+ export interface ConfigStore {
21
+ readonly path: string
22
+ all: Record<string, unknown>
23
+ readonly size: number
24
+ get: (key: string) => unknown
25
+ set: (key: string | Record<string, unknown>, value?: unknown) => void
26
+ has: (key: string) => boolean
27
+ delete: (key: string) => void
28
+ clear: () => void
29
+ }
30
+
31
+ let configStore: ConfigStore | null = null
32
+
33
+ export const getConfigStore = (): ConfigStore => {
34
+ configStore ??= createConfigStore()
35
+ return configStore
36
+ }
37
+
38
+ /** Replace the store, e.g., with an in-memory one for a test. */
39
+ export const setConfigStore = (store: ConfigStore): void => {
40
+ configStore = store
41
+ }
42
+
43
+ /** Drop the current store so the next read builds the real one. */
44
+ export const resetConfigStore = (): void => {
45
+ configStore = null
46
+ }
47
+
48
+ const createConfigStore = (): PersistentConfigStore => {
15
49
  const settingsStore = new Configstore(legacyConfigStoreId, undefined, {
16
50
  configPath: getConfigPath(),
17
51
  })
@@ -25,61 +59,10 @@ export const getConfigStore = () => {
25
59
  new Configstore(legacyConfigStoreId),
26
60
  )
27
61
 
28
- return new SeamConfigStore(settingsStore, stateStore)
62
+ return new PersistentConfigStore(settingsStore, stateStore)
29
63
  }
30
64
 
31
- export const mergeConfig = (
32
- baseConfig: Record<string, unknown>,
33
- overrideConfig: Record<string, unknown>,
34
- ): Record<string, unknown> => {
35
- const mergedConfig = { ...baseConfig }
36
-
37
- for (const [key, value] of Object.entries(overrideConfig)) {
38
- const baseValue = mergedConfig[key]
39
- mergedConfig[key] =
40
- isRecord(baseValue) && isRecord(value)
41
- ? mergeConfig(baseValue, value)
42
- : value
43
- }
44
-
45
- return mergedConfig
46
- }
47
-
48
- export const splitConfig = (
49
- config: Record<string, unknown>,
50
- ): {
51
- settings: Record<string, unknown>
52
- state: Record<string, unknown>
53
- } => {
54
- const settings: Record<string, unknown> = {}
55
- const state: Record<string, unknown> = {}
56
-
57
- for (const [key, value] of Object.entries(config)) {
58
- if (isStateKey(key)) {
59
- state[key] = value
60
- continue
61
- }
62
-
63
- if (isRecord(value)) {
64
- const splitValue = splitConfig(value)
65
- if (Object.keys(splitValue.settings).length > 0) {
66
- settings[key] = splitValue.settings
67
- }
68
-
69
- if (Object.keys(splitValue.state).length > 0) {
70
- state[key] = splitValue.state
71
- }
72
-
73
- continue
74
- }
75
-
76
- settings[key] = value
77
- }
78
-
79
- return { settings, state }
80
- }
81
-
82
- class SeamConfigStore {
65
+ export class PersistentConfigStore implements ConfigStore {
83
66
  readonly path: string
84
67
 
85
68
  constructor(
@@ -145,14 +128,6 @@ const getStateConfigPath = (): string => {
145
128
  return join(paths.log, configFileName)
146
129
  }
147
130
 
148
- const isStateKey = (key: string): boolean => {
149
- return (
150
- key === currentWorkspaceIdKey ||
151
- key === patKey ||
152
- key.endsWith(`.${patKey}`)
153
- )
154
- }
155
-
156
131
  const isRecord = (value: unknown): value is Record<string, unknown> => {
157
132
  return value != null && typeof value === 'object' && !Array.isArray(value)
158
133
  }
@@ -1 +1,8 @@
1
- export { getConfigStore } from './config-store.js'
1
+ export {
2
+ type ConfigStore,
3
+ getConfigStore,
4
+ type PersistentConfigStore,
5
+ resetConfigStore,
6
+ setConfigStore,
7
+ } from './config-store.js'
8
+ export { createMemoryConfigStore } from './memory-config-store.js'
@@ -0,0 +1,62 @@
1
+ import type { ConfigStore } from './config-store.js'
2
+
3
+ /**
4
+ * A real {@link ConfigStore} held in memory, for tests.
5
+ *
6
+ * Keys are flat: the file-backed store nests dotted keys, but nothing reads
7
+ * a value back by a different spelling than it was written with.
8
+ */
9
+ export class MemoryConfigStore implements ConfigStore {
10
+ readonly path = '/memory/cli.json'
11
+
12
+ private readonly values: Map<string, unknown>
13
+
14
+ constructor(initialValues: Record<string, unknown> = {}) {
15
+ this.values = new Map(Object.entries(initialValues))
16
+ }
17
+
18
+ get all(): Record<string, unknown> {
19
+ return Object.fromEntries(this.values)
20
+ }
21
+
22
+ set all(newValues: Record<string, unknown>) {
23
+ this.values.clear()
24
+ for (const [key, value] of Object.entries(newValues)) {
25
+ this.values.set(key, value)
26
+ }
27
+ }
28
+
29
+ get size(): number {
30
+ return this.values.size
31
+ }
32
+
33
+ get(key: string): unknown {
34
+ return this.values.get(key)
35
+ }
36
+
37
+ set(key: string | Record<string, unknown>, value?: unknown): void {
38
+ if (typeof key === 'string') {
39
+ this.values.set(key, value)
40
+ return
41
+ }
42
+ for (const [configKey, configValue] of Object.entries(key)) {
43
+ this.values.set(configKey, configValue)
44
+ }
45
+ }
46
+
47
+ has(key: string): boolean {
48
+ return this.values.has(key)
49
+ }
50
+
51
+ delete(key: string): void {
52
+ this.values.delete(key)
53
+ }
54
+
55
+ clear(): void {
56
+ this.values.clear()
57
+ }
58
+ }
59
+
60
+ export const createMemoryConfigStore = (
61
+ initialValues: Record<string, unknown> = {},
62
+ ): ConfigStore => new MemoryConfigStore(initialValues)
@@ -2,7 +2,7 @@ import { existsSync, rmSync } from 'node:fs'
2
2
 
3
3
  import type Configstore from 'configstore'
4
4
 
5
- import { mergeConfig, splitConfig } from './config-store.js'
5
+ import { mergeConfig, splitConfig } from './values.js'
6
6
 
7
7
  export const migrateConfigStore = (
8
8
  settingsStore: Configstore,
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Config values as whole trees: merging two trees into one view, and
3
+ * splitting one tree into the settings file and the state file by key.
4
+ * Pure transforms shared by the persistent store and the legacy migration.
5
+ */
6
+
7
+ const currentWorkspaceIdKey = 'current_workspace_id'
8
+ const patKey = 'pat'
9
+
10
+ /** Whether a key holds auth state rather than a setting. */
11
+ export const isStateKey = (key: string): boolean => {
12
+ return (
13
+ key === currentWorkspaceIdKey ||
14
+ key === patKey ||
15
+ key.endsWith(`.${patKey}`)
16
+ )
17
+ }
18
+
19
+ export const mergeConfig = (
20
+ baseConfig: Record<string, unknown>,
21
+ overrideConfig: Record<string, unknown>,
22
+ ): Record<string, unknown> => {
23
+ const mergedConfig = { ...baseConfig }
24
+
25
+ for (const [key, value] of Object.entries(overrideConfig)) {
26
+ const baseValue = mergedConfig[key]
27
+ mergedConfig[key] =
28
+ isRecord(baseValue) && isRecord(value)
29
+ ? mergeConfig(baseValue, value)
30
+ : value
31
+ }
32
+
33
+ return mergedConfig
34
+ }
35
+
36
+ export const splitConfig = (
37
+ config: Record<string, unknown>,
38
+ ): {
39
+ settings: Record<string, unknown>
40
+ state: Record<string, unknown>
41
+ } => {
42
+ const settings: Record<string, unknown> = {}
43
+ const state: Record<string, unknown> = {}
44
+
45
+ for (const [key, value] of Object.entries(config)) {
46
+ if (isStateKey(key)) {
47
+ state[key] = value
48
+ continue
49
+ }
50
+
51
+ if (isRecord(value)) {
52
+ const splitValue = splitConfig(value)
53
+ if (Object.keys(splitValue.settings).length > 0) {
54
+ settings[key] = splitValue.settings
55
+ }
56
+
57
+ if (Object.keys(splitValue.state).length > 0) {
58
+ state[key] = splitValue.state
59
+ }
60
+
61
+ continue
62
+ }
63
+
64
+ settings[key] = value
65
+ }
66
+
67
+ return { settings, state }
68
+ }
69
+
70
+ const isRecord = (value: unknown): value is Record<string, unknown> => {
71
+ return value != null && typeof value === 'object' && !Array.isArray(value)
72
+ }