@zuplo/cli 6.69.3 → 6.69.5

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 (392) hide show
  1. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts +2 -0
  2. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts.map +1 -0
  3. package/dist/__tests__/integration/confirm-linked-config.integration.test.js +202 -0
  4. package/dist/__tests__/integration/confirm-linked-config.integration.test.js.map +1 -0
  5. package/dist/__tests__/integration/info.integration.test.js +49 -2
  6. package/dist/__tests__/integration/info.integration.test.js.map +1 -1
  7. package/dist/__tests__/integration/jest-mocks-setup.js +29 -10
  8. package/dist/__tests__/integration/jest-mocks-setup.js.map +1 -1
  9. package/dist/__tests__/integration/linked-config-cascade.integration.test.js +36 -0
  10. package/dist/__tests__/integration/linked-config-cascade.integration.test.js.map +1 -1
  11. package/dist/cmds/custom-domain/index.d.ts.map +1 -1
  12. package/dist/cmds/custom-domain/index.js +6 -10
  13. package/dist/cmds/custom-domain/index.js.map +1 -1
  14. package/dist/cmds/delete.d.ts.map +1 -1
  15. package/dist/cmds/delete.js +2 -0
  16. package/dist/cmds/delete.js.map +1 -1
  17. package/dist/cmds/deploy.d.ts.map +1 -1
  18. package/dist/cmds/deploy.js +2 -0
  19. package/dist/cmds/deploy.js.map +1 -1
  20. package/dist/cmds/link.d.ts.map +1 -1
  21. package/dist/cmds/link.js +2 -0
  22. package/dist/cmds/link.js.map +1 -1
  23. package/dist/cmds/list.d.ts.map +1 -1
  24. package/dist/cmds/list.js +2 -0
  25. package/dist/cmds/list.js.map +1 -1
  26. package/dist/cmds/mtls-certificates/create.d.ts.map +1 -1
  27. package/dist/cmds/mtls-certificates/create.js +2 -0
  28. package/dist/cmds/mtls-certificates/create.js.map +1 -1
  29. package/dist/cmds/mtls-certificates/delete.d.ts.map +1 -1
  30. package/dist/cmds/mtls-certificates/delete.js +2 -0
  31. package/dist/cmds/mtls-certificates/delete.js.map +1 -1
  32. package/dist/cmds/mtls-certificates/describe.d.ts.map +1 -1
  33. package/dist/cmds/mtls-certificates/describe.js +2 -0
  34. package/dist/cmds/mtls-certificates/describe.js.map +1 -1
  35. package/dist/cmds/mtls-certificates/disable.d.ts.map +1 -1
  36. package/dist/cmds/mtls-certificates/disable.js +2 -0
  37. package/dist/cmds/mtls-certificates/disable.js.map +1 -1
  38. package/dist/cmds/mtls-certificates/index.d.ts.map +1 -1
  39. package/dist/cmds/mtls-certificates/index.js +8 -12
  40. package/dist/cmds/mtls-certificates/index.js.map +1 -1
  41. package/dist/cmds/mtls-certificates/list.d.ts.map +1 -1
  42. package/dist/cmds/mtls-certificates/list.js +2 -0
  43. package/dist/cmds/mtls-certificates/list.js.map +1 -1
  44. package/dist/cmds/mtls-certificates/update.d.ts.map +1 -1
  45. package/dist/cmds/mtls-certificates/update.js +2 -0
  46. package/dist/cmds/mtls-certificates/update.js.map +1 -1
  47. package/dist/cmds/open-api/index.d.ts.map +1 -1
  48. package/dist/cmds/open-api/index.js +2 -5
  49. package/dist/cmds/open-api/index.js.map +1 -1
  50. package/dist/cmds/project/index.d.ts.map +1 -1
  51. package/dist/cmds/project/index.js +2 -5
  52. package/dist/cmds/project/index.js.map +1 -1
  53. package/dist/cmds/proxies/index.d.ts +4 -4
  54. package/dist/cmds/proxies/index.d.ts.map +1 -1
  55. package/dist/cmds/proxies/index.js +6 -10
  56. package/dist/cmds/proxies/index.js.map +1 -1
  57. package/dist/cmds/source/index.d.ts.map +1 -1
  58. package/dist/cmds/source/index.js +2 -9
  59. package/dist/cmds/source/index.js.map +1 -1
  60. package/dist/cmds/source/migrate.d.ts +4 -4
  61. package/dist/cmds/source/migrate.d.ts.map +1 -1
  62. package/dist/cmds/source/migrate.js +3 -6
  63. package/dist/cmds/source/migrate.js.map +1 -1
  64. package/dist/cmds/tunnel/index.d.ts.map +1 -1
  65. package/dist/cmds/tunnel/index.js +8 -12
  66. package/dist/cmds/tunnel/index.js.map +1 -1
  67. package/dist/cmds/tunnel/services/index.d.ts.map +1 -1
  68. package/dist/cmds/tunnel/services/index.js +2 -5
  69. package/dist/cmds/tunnel/services/index.js.map +1 -1
  70. package/dist/cmds/variable/create.d.ts.map +1 -1
  71. package/dist/cmds/variable/create.js +2 -0
  72. package/dist/cmds/variable/create.js.map +1 -1
  73. package/dist/cmds/variable/index.d.ts.map +1 -1
  74. package/dist/cmds/variable/index.js +2 -5
  75. package/dist/cmds/variable/index.js.map +1 -1
  76. package/dist/cmds/variable/update.d.ts.map +1 -1
  77. package/dist/cmds/variable/update.js +2 -0
  78. package/dist/cmds/variable/update.js.map +1 -1
  79. package/dist/common/handler.d.ts +4 -1
  80. package/dist/common/handler.d.ts.map +1 -1
  81. package/dist/common/handler.js +11 -2
  82. package/dist/common/handler.js.map +1 -1
  83. package/dist/common/middleware/confirm-linked-config.d.ts +4 -0
  84. package/dist/common/middleware/confirm-linked-config.d.ts.map +1 -0
  85. package/dist/common/middleware/confirm-linked-config.js +30 -0
  86. package/dist/common/middleware/confirm-linked-config.js.map +1 -0
  87. package/dist/common/middleware/get-environment-param.d.ts.map +1 -1
  88. package/dist/common/middleware/get-environment-param.js +2 -18
  89. package/dist/common/middleware/get-environment-param.js.map +1 -1
  90. package/dist/common/utils/build-environment-prompt-choices.d.ts +13 -0
  91. package/dist/common/utils/build-environment-prompt-choices.d.ts.map +1 -0
  92. package/dist/common/utils/build-environment-prompt-choices.js +66 -0
  93. package/dist/common/utils/build-environment-prompt-choices.js.map +1 -0
  94. package/dist/common/utils/build-environment-prompt-choices.test.d.ts +2 -0
  95. package/dist/common/utils/build-environment-prompt-choices.test.d.ts.map +1 -0
  96. package/dist/common/utils/build-environment-prompt-choices.test.js +97 -0
  97. package/dist/common/utils/build-environment-prompt-choices.test.js.map +1 -0
  98. package/dist/common/utils/format-environment-type.d.ts +2 -0
  99. package/dist/common/utils/format-environment-type.d.ts.map +1 -0
  100. package/dist/common/utils/format-environment-type.js +12 -0
  101. package/dist/common/utils/format-environment-type.js.map +1 -0
  102. package/dist/common/utils/format-environment-type.test.d.ts +2 -0
  103. package/dist/common/utils/format-environment-type.test.d.ts.map +1 -0
  104. package/dist/common/utils/format-environment-type.test.js +32 -0
  105. package/dist/common/utils/format-environment-type.test.js.map +1 -0
  106. package/dist/common/utils/pretty-print-environment-prompt.d.ts +1 -4
  107. package/dist/common/utils/pretty-print-environment-prompt.d.ts.map +1 -1
  108. package/dist/common/utils/pretty-print-environment-prompt.js +6 -14
  109. package/dist/common/utils/pretty-print-environment-prompt.js.map +1 -1
  110. package/dist/common/utils/pretty-print-environment-prompt.test.js +15 -17
  111. package/dist/common/utils/pretty-print-environment-prompt.test.js.map +1 -1
  112. package/dist/common/utils/sort-environments-for-prompt.d.ts +5 -0
  113. package/dist/common/utils/sort-environments-for-prompt.d.ts.map +1 -0
  114. package/dist/common/utils/sort-environments-for-prompt.js +27 -0
  115. package/dist/common/utils/sort-environments-for-prompt.js.map +1 -0
  116. package/dist/common/utils/sort-environments-for-prompt.test.d.ts +2 -0
  117. package/dist/common/utils/sort-environments-for-prompt.test.d.ts.map +1 -0
  118. package/dist/common/utils/sort-environments-for-prompt.test.js +82 -0
  119. package/dist/common/utils/sort-environments-for-prompt.test.js.map +1 -0
  120. package/dist/project/info/handler.d.ts.map +1 -1
  121. package/dist/project/info/handler.js +5 -1
  122. package/dist/project/info/handler.js.map +1 -1
  123. package/dist/tsconfig.tsbuildinfo +1 -1
  124. package/node_modules/@fastify/proxy-addr/node_modules/ipaddr.js/README.md +1 -5
  125. package/node_modules/@fastify/proxy-addr/node_modules/ipaddr.js/ipaddr.min.js +1 -1
  126. package/node_modules/@fastify/proxy-addr/node_modules/ipaddr.js/lib/ipaddr.js +21 -6
  127. package/node_modules/@fastify/proxy-addr/node_modules/ipaddr.js/package.json +1 -1
  128. package/node_modules/@zuplo/core/index.minified.js +141 -137
  129. package/node_modules/@zuplo/core/package.json +1 -1
  130. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/.github/workflows/ci.yml +1 -1
  131. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/.github/workflows/lock-threads.yml +19 -0
  132. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/LICENSE +1 -3
  133. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/benchmark/bench-cmp-lib.js +60 -44
  134. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/index.js +2 -2
  135. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/package.json +7 -7
  136. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/anyof.test.js +20 -0
  137. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/array.test.js +22 -0
  138. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/debug-mode.test.js +21 -0
  139. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/if-then-else.test.js +72 -0
  140. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/invalidSchema.test.js +20 -0
  141. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/issue-836.test.js +183 -0
  142. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/json-add-comma.test.js +57 -57
  143. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/oneof.test.js +20 -0
  144. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/ref.test.js +31 -0
  145. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/test/typebox.test.js +1 -1
  146. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/types/{index.test-d.ts → index.tst.ts} +17 -17
  147. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
  148. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
  149. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
  150. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
  151. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1380 -0
  152. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
  153. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/index.js +1686 -0
  154. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
  155. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
  156. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
  157. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
  158. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
  159. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/perf.js +11 -0
  160. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
  161. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
  162. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
  163. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +2 -2
  164. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +4 -7
  165. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/index.d.ts +2 -3
  166. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
  167. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/index.js +10 -16
  168. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
  169. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/index.min.js +1 -1
  170. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/index.min.js.map +4 -4
  171. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
  172. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
  173. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
  174. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
  175. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1380 -0
  176. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
  177. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/index.js +1686 -0
  178. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
  179. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
  180. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
  181. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
  182. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
  183. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/perf.js +11 -0
  184. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
  185. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
  186. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
  187. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/perf.js +11 -0
  188. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
  189. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
  190. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
  191. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +1 -1
  192. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +1 -1
  193. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/index.d.ts +2 -3
  194. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -1
  195. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/index.js +9 -15
  196. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -1
  197. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/index.min.js +1 -1
  198. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/index.min.js.map +4 -4
  199. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
  200. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
  201. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/perf.js +8 -0
  202. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
  203. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -1
  204. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -1
  205. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/index.d.ts +2 -3
  206. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
  207. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/index.js +9 -15
  208. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/index.js.map +1 -1
  209. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/index.min.js +1 -1
  210. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/index.min.js.map +4 -4
  211. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
  212. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
  213. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +1 -1
  214. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +2 -3
  215. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/index.d.ts +2 -3
  216. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -1
  217. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/index.js +9 -15
  218. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/index.js.map +1 -1
  219. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/index.min.js +1 -1
  220. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/index.min.js.map +4 -4
  221. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
  222. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
  223. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/perf.js +8 -0
  224. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
  225. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
  226. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
  227. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/perf.js +8 -0
  228. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
  229. package/node_modules/@zuplo/editor/node_modules/lru-cache/package.json +44 -16
  230. package/node_modules/@zuplo/graphql/package.json +1 -1
  231. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  232. package/node_modules/@zuplo/otel/package.json +1 -1
  233. package/node_modules/@zuplo/runtime/out/esm/index.js +54 -54
  234. package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
  235. package/node_modules/@zuplo/runtime/out/types/index.d.ts +4 -0
  236. package/node_modules/@zuplo/runtime/package.json +1 -1
  237. package/node_modules/axios/CHANGELOG.md +32 -6
  238. package/node_modules/axios/README.md +356 -20
  239. package/node_modules/axios/dist/axios.js +1389 -1071
  240. package/node_modules/axios/dist/axios.js.map +1 -1
  241. package/node_modules/axios/dist/axios.min.js +3 -3
  242. package/node_modules/axios/dist/axios.min.js.map +1 -1
  243. package/node_modules/axios/dist/browser/axios.cjs +1486 -1123
  244. package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
  245. package/node_modules/axios/dist/esm/axios.js +1488 -1124
  246. package/node_modules/axios/dist/esm/axios.js.map +1 -1
  247. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  248. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  249. package/node_modules/axios/dist/node/axios.cjs +1230 -871
  250. package/node_modules/axios/dist/node/axios.cjs.map +1 -1
  251. package/node_modules/axios/index.d.cts +25 -13
  252. package/node_modules/axios/index.d.ts +21 -4
  253. package/node_modules/axios/index.js +2 -0
  254. package/node_modules/axios/lib/adapters/adapters.js +4 -2
  255. package/node_modules/axios/lib/adapters/fetch.js +126 -10
  256. package/node_modules/axios/lib/adapters/http.js +178 -59
  257. package/node_modules/axios/lib/adapters/xhr.js +6 -2
  258. package/node_modules/axios/lib/core/Axios.js +7 -3
  259. package/node_modules/axios/lib/core/AxiosError.js +86 -1
  260. package/node_modules/axios/lib/core/AxiosHeaders.js +3 -0
  261. package/node_modules/axios/lib/core/dispatchRequest.js +19 -7
  262. package/node_modules/axios/lib/core/mergeConfig.js +6 -3
  263. package/node_modules/axios/lib/core/settle.js +7 -11
  264. package/node_modules/axios/lib/defaults/index.js +1 -1
  265. package/node_modules/axios/lib/env/data.js +1 -1
  266. package/node_modules/axios/lib/helpers/buildURL.js +1 -1
  267. package/node_modules/axios/lib/helpers/cookies.js +14 -2
  268. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +28 -1
  269. package/node_modules/axios/lib/helpers/formDataToStream.js +1 -1
  270. package/node_modules/axios/lib/helpers/parseProtocol.js +1 -1
  271. package/node_modules/axios/lib/helpers/resolveConfig.js +33 -17
  272. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +26 -1
  273. package/node_modules/axios/lib/helpers/validator.js +1 -1
  274. package/node_modules/axios/lib/utils.js +27 -15
  275. package/node_modules/axios/package.json +17 -24
  276. package/node_modules/fast-uri/.github/workflows/ci.yml +12 -7
  277. package/node_modules/fast-uri/.github/workflows/lock-threads.yml +19 -0
  278. package/node_modules/fast-uri/.github/workflows/package-manager-ci.yml +1 -1
  279. package/node_modules/fast-uri/LICENSE +1 -3
  280. package/node_modules/fast-uri/README.md +13 -4
  281. package/node_modules/fast-uri/index.js +90 -24
  282. package/node_modules/fast-uri/lib/utils.js +129 -22
  283. package/node_modules/fast-uri/package.json +3 -4
  284. package/node_modules/fast-uri/test/equal.test.js +9 -0
  285. package/node_modules/fast-uri/test/parse.test.js +5 -0
  286. package/node_modules/fast-uri/test/resolve.test.js +9 -0
  287. package/node_modules/fast-uri/test/security-normalization.test.js +39 -0
  288. package/node_modules/fast-uri/test/security.test.js +133 -0
  289. package/node_modules/is-core-module/CHANGELOG.md +244 -113
  290. package/node_modules/is-core-module/README.md +1 -1
  291. package/node_modules/is-core-module/core.json +12 -12
  292. package/node_modules/is-core-module/package.json +5 -5
  293. package/node_modules/is-core-module/test/index.js +101 -0
  294. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
  295. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
  296. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
  297. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
  298. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1380 -0
  299. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
  300. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/index.js +1686 -0
  301. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
  302. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
  303. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
  304. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
  305. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
  306. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/perf.js +11 -0
  307. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
  308. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
  309. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
  310. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +2 -2
  311. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +4 -7
  312. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/index.d.ts +2 -3
  313. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
  314. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/index.js +10 -16
  315. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
  316. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/index.min.js +1 -1
  317. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/index.min.js.map +4 -4
  318. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
  319. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
  320. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
  321. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
  322. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1380 -0
  323. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
  324. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/index.js +1686 -0
  325. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
  326. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
  327. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
  328. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
  329. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
  330. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/perf.js +11 -0
  331. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
  332. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
  333. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
  334. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/perf.js +11 -0
  335. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
  336. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
  337. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
  338. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +1 -1
  339. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +1 -1
  340. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/index.d.ts +2 -3
  341. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -1
  342. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/index.js +9 -15
  343. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -1
  344. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/index.min.js +1 -1
  345. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/index.min.js.map +4 -4
  346. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
  347. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
  348. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/perf.js +8 -0
  349. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
  350. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -1
  351. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -1
  352. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/index.d.ts +2 -3
  353. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
  354. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/index.js +9 -15
  355. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/index.js.map +1 -1
  356. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/index.min.js +1 -1
  357. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/index.min.js.map +4 -4
  358. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
  359. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
  360. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +1 -1
  361. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +2 -3
  362. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/index.d.ts +2 -3
  363. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -1
  364. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/index.js +9 -15
  365. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/index.js.map +1 -1
  366. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/index.min.js +1 -1
  367. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/index.min.js.map +4 -4
  368. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
  369. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
  370. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/perf.js +8 -0
  371. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
  372. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
  373. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
  374. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/perf.js +8 -0
  375. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
  376. package/node_modules/rimraf/node_modules/lru-cache/package.json +44 -16
  377. package/package.json +6 -6
  378. package/node_modules/@zuplo/editor/node_modules/fast-json-stringify/.github/stale.yml +0 -21
  379. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts.map +0 -1
  380. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js.map +0 -1
  381. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.mts.map +0 -1
  382. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.mjs.map +0 -1
  383. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.mts.map +0 -1
  384. package/node_modules/@zuplo/editor/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.mjs.map +0 -1
  385. package/node_modules/fast-uri/.github/.stale.yml +0 -21
  386. package/node_modules/fast-uri/.github/tests_checker.yml +0 -8
  387. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts.map +0 -1
  388. package/node_modules/rimraf/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js.map +0 -1
  389. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.mts.map +0 -1
  390. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.mjs.map +0 -1
  391. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.mts.map +0 -1
  392. package/node_modules/rimraf/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.mjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=confirm-linked-config.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-linked-config.integration.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/confirm-linked-config.integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,202 @@
1
+ import { confirmLinkedConfig } from "../../common/middleware/confirm-linked-config.js";
2
+ import { confirmLinkedValue, readLinkedConfig, USE_LINKED_DETAILS, } from "../../common/read-linked-config.js";
3
+ import { isInteractiveTerminal } from "../../common/terminal.js";
4
+ import { cleanupTest, setupTestEnvironment, TEST_ACCOUNT_NAME, TEST_AUTH_TOKEN, TEST_PROJECT_NAME, } from "./test-utils.js";
5
+ jest.mock("../../common/read-linked-config.js", () => ({
6
+ __esModule: true,
7
+ confirmLinkedValue: jest.fn().mockResolvedValue(true),
8
+ readLinkedConfig: jest.fn().mockResolvedValue({}),
9
+ USE_LINKED_DETAILS: "useLinkedDetails",
10
+ ignoreLinkedDetails: jest
11
+ .fn()
12
+ .mockImplementation((argv) => {
13
+ argv["useLinkedDetails"] = false;
14
+ }),
15
+ }));
16
+ jest.mock("../../common/terminal.js", () => ({
17
+ __esModule: true,
18
+ isInteractiveTerminal: jest.fn().mockReturnValue(true),
19
+ }));
20
+ describe("confirmLinkedConfig middleware", () => {
21
+ beforeEach(() => {
22
+ setupTestEnvironment();
23
+ jest.clearAllMocks();
24
+ jest.mocked(isInteractiveTerminal).mockReturnValue(true);
25
+ jest.mocked(confirmLinkedValue).mockResolvedValue(true);
26
+ jest.mocked(readLinkedConfig).mockResolvedValue({});
27
+ });
28
+ afterEach(() => {
29
+ cleanupTest();
30
+ });
31
+ describe("when both account and project are linked and the terminal is interactive", () => {
32
+ it("asks a single combined Y/n prompt and sets both values on accept", async () => {
33
+ jest.mocked(readLinkedConfig).mockResolvedValue({
34
+ accountName: TEST_ACCOUNT_NAME,
35
+ projectName: TEST_PROJECT_NAME,
36
+ });
37
+ jest.mocked(confirmLinkedValue).mockResolvedValue(true);
38
+ const argv = { authToken: TEST_AUTH_TOKEN };
39
+ await confirmLinkedConfig(argv);
40
+ expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
41
+ expect(confirmLinkedValue).toHaveBeenCalledWith(`Use linked project '${TEST_PROJECT_NAME}' in account '${TEST_ACCOUNT_NAME}'?`);
42
+ expect(argv.account).toBe(TEST_ACCOUNT_NAME);
43
+ expect(argv.project).toBe(TEST_PROJECT_NAME);
44
+ expect(argv[USE_LINKED_DETAILS]).not.toBe(false);
45
+ });
46
+ it("sets useLinkedDetails=false on decline so downstream pickers run", async () => {
47
+ jest.mocked(readLinkedConfig).mockResolvedValue({
48
+ accountName: TEST_ACCOUNT_NAME,
49
+ projectName: TEST_PROJECT_NAME,
50
+ });
51
+ jest.mocked(confirmLinkedValue).mockResolvedValue(false);
52
+ const argv = { authToken: TEST_AUTH_TOKEN };
53
+ await confirmLinkedConfig(argv);
54
+ expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
55
+ expect(argv[USE_LINKED_DETAILS]).toBe(false);
56
+ expect(argv.account).toBeUndefined();
57
+ expect(argv.project).toBeUndefined();
58
+ });
59
+ });
60
+ describe("when the terminal is non-interactive (CI/CD)", () => {
61
+ it("silently uses both linked values without prompting", async () => {
62
+ jest.mocked(readLinkedConfig).mockResolvedValue({
63
+ accountName: TEST_ACCOUNT_NAME,
64
+ projectName: TEST_PROJECT_NAME,
65
+ });
66
+ jest.mocked(isInteractiveTerminal).mockReturnValue(false);
67
+ const argv = { authToken: TEST_AUTH_TOKEN };
68
+ await confirmLinkedConfig(argv);
69
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
70
+ expect(argv.account).toBe(TEST_ACCOUNT_NAME);
71
+ expect(argv.project).toBe(TEST_PROJECT_NAME);
72
+ });
73
+ });
74
+ describe("when one of --account or --project is already supplied", () => {
75
+ it("skips entirely when --account is supplied (defers to fetchProject)", async () => {
76
+ jest.mocked(readLinkedConfig).mockResolvedValue({
77
+ accountName: TEST_ACCOUNT_NAME,
78
+ projectName: TEST_PROJECT_NAME,
79
+ });
80
+ const argv = {
81
+ authToken: TEST_AUTH_TOKEN,
82
+ account: "explicit-account",
83
+ };
84
+ await confirmLinkedConfig(argv);
85
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
86
+ expect(readLinkedConfig).not.toHaveBeenCalled();
87
+ expect(argv.account).toBe("explicit-account");
88
+ expect(argv.project).toBeUndefined();
89
+ });
90
+ it("skips entirely when --project is supplied (defers to fetchAccount)", async () => {
91
+ jest.mocked(readLinkedConfig).mockResolvedValue({
92
+ accountName: TEST_ACCOUNT_NAME,
93
+ projectName: TEST_PROJECT_NAME,
94
+ });
95
+ const argv = {
96
+ authToken: TEST_AUTH_TOKEN,
97
+ project: "explicit-project",
98
+ };
99
+ await confirmLinkedConfig(argv);
100
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
101
+ expect(readLinkedConfig).not.toHaveBeenCalled();
102
+ expect(argv.project).toBe("explicit-project");
103
+ expect(argv.account).toBeUndefined();
104
+ });
105
+ it("skips entirely when both flags are supplied", async () => {
106
+ const argv = {
107
+ authToken: TEST_AUTH_TOKEN,
108
+ account: "explicit-account",
109
+ project: "explicit-project",
110
+ };
111
+ await confirmLinkedConfig(argv);
112
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
113
+ expect(readLinkedConfig).not.toHaveBeenCalled();
114
+ });
115
+ it("skips entirely when --account is supplied as an array (repeated flag)", async () => {
116
+ jest.mocked(readLinkedConfig).mockResolvedValue({
117
+ accountName: TEST_ACCOUNT_NAME,
118
+ projectName: TEST_PROJECT_NAME,
119
+ });
120
+ const argv = {
121
+ authToken: TEST_AUTH_TOKEN,
122
+ account: ["a", "b"],
123
+ };
124
+ await confirmLinkedConfig(argv);
125
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
126
+ expect(readLinkedConfig).not.toHaveBeenCalled();
127
+ expect(argv.account).toEqual(["a", "b"]);
128
+ });
129
+ });
130
+ describe("when --no-prompt is set (argv.prompt === false)", () => {
131
+ it("auto-accepts both linked values without prompting", async () => {
132
+ jest.mocked(readLinkedConfig).mockResolvedValue({
133
+ accountName: TEST_ACCOUNT_NAME,
134
+ projectName: TEST_PROJECT_NAME,
135
+ });
136
+ const argv = {
137
+ authToken: TEST_AUTH_TOKEN,
138
+ prompt: false,
139
+ };
140
+ await confirmLinkedConfig(argv);
141
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
142
+ expect(argv.account).toBe(TEST_ACCOUNT_NAME);
143
+ expect(argv.project).toBe(TEST_PROJECT_NAME);
144
+ });
145
+ });
146
+ describe("when the linked config is partial", () => {
147
+ it("skips when only the account is linked (defers to fetchAccount's single prompt)", async () => {
148
+ jest.mocked(readLinkedConfig).mockResolvedValue({
149
+ accountName: TEST_ACCOUNT_NAME,
150
+ });
151
+ const argv = { authToken: TEST_AUTH_TOKEN };
152
+ await confirmLinkedConfig(argv);
153
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
154
+ expect(argv.account).toBeUndefined();
155
+ expect(argv.project).toBeUndefined();
156
+ });
157
+ it("skips when only the project is linked", async () => {
158
+ jest.mocked(readLinkedConfig).mockResolvedValue({
159
+ projectName: TEST_PROJECT_NAME,
160
+ });
161
+ const argv = { authToken: TEST_AUTH_TOKEN };
162
+ await confirmLinkedConfig(argv);
163
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
164
+ expect(argv.account).toBeUndefined();
165
+ expect(argv.project).toBeUndefined();
166
+ });
167
+ it("skips when no linked config exists", async () => {
168
+ jest.mocked(readLinkedConfig).mockResolvedValue({});
169
+ const argv = { authToken: TEST_AUTH_TOKEN };
170
+ await confirmLinkedConfig(argv);
171
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
172
+ });
173
+ });
174
+ describe("when useLinkedDetails is already false (link command path)", () => {
175
+ it("skips entirely without reading linked config", async () => {
176
+ const argv = {
177
+ authToken: TEST_AUTH_TOKEN,
178
+ [USE_LINKED_DETAILS]: false,
179
+ };
180
+ await confirmLinkedConfig(argv);
181
+ expect(readLinkedConfig).not.toHaveBeenCalled();
182
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
183
+ expect(argv[USE_LINKED_DETAILS]).toBe(false);
184
+ });
185
+ });
186
+ describe("when an api-key is supplied", () => {
187
+ it("skips entirely (account is resolved via the api-key)", async () => {
188
+ jest.mocked(readLinkedConfig).mockResolvedValue({
189
+ accountName: TEST_ACCOUNT_NAME,
190
+ projectName: TEST_PROJECT_NAME,
191
+ });
192
+ const argv = {
193
+ authToken: TEST_AUTH_TOKEN,
194
+ "api-key": "zpka_some_key",
195
+ };
196
+ await confirmLinkedConfig(argv);
197
+ expect(confirmLinkedValue).not.toHaveBeenCalled();
198
+ expect(readLinkedConfig).not.toHaveBeenCalled();
199
+ });
200
+ });
201
+ });
202
+ //# sourceMappingURL=confirm-linked-config.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-linked-config.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/confirm-linked-config.integration.test.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AACvF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,IAAI,CAAC,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,UAAU,EAAE,IAAI;IAChB,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC;IACrD,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACjD,kBAAkB,EAAE,kBAAkB;IACtC,mBAAmB,EAAE,IAAI;SACtB,EAAE,EAAE;SACJ,kBAAkB,CAAC,CAAC,IAA6B,EAAE,EAAE;QACpD,IAAI,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;IACnC,CAAC,CAAC;CACL,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC3C,UAAU,EAAE,IAAI;IAChB,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;CACvD,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,UAAU,CAAC,GAAG,EAAE;QACd,oBAAoB,EAAE,CAAC;QACvB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0EAA0E,EAAE,GAAG,EAAE;QACxF,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAExD,MAAM,IAAI,GAA4B,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;YACrE,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACpD,MAAM,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAC7C,uBAAuB,iBAAiB,iBAAiB,iBAAiB,IAAI,CAC/E,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAEzD,MAAM,IAAI,GAA4B,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;YACrE,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACpD,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;QAC5D,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAE1D,MAAM,IAAI,GAA4B,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;YACrE,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACtE,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;YAClF,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAA4B;gBACpC,SAAS,EAAE,eAAe;gBAC1B,OAAO,EAAE,kBAAkB;aAC5B,CAAC;YACF,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;YAClF,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAA4B;gBACpC,SAAS,EAAE,eAAe;gBAC1B,OAAO,EAAE,kBAAkB;aAC5B,CAAC;YACF,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,IAAI,GAA4B;gBACpC,SAAS,EAAE,eAAe;gBAC1B,OAAO,EAAE,kBAAkB;gBAC3B,OAAO,EAAE,kBAAkB;aAC5B,CAAC;YACF,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;YACrF,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAA4B;gBACpC,SAAS,EAAE,eAAe;gBAC1B,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;aACpB,CAAC;YACF,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC/D,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAA4B;gBACpC,SAAS,EAAE,eAAe;gBAC1B,MAAM,EAAE,KAAK;aACd,CAAC;YACF,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACjD,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;YAC9F,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAA4B,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;YACrE,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAA4B,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;YACrE,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClD,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAEpD,MAAM,IAAI,GAA4B,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;YACrE,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,4DAA4D,EAAE,GAAG,EAAE;QAC1E,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC5D,MAAM,IAAI,GAA4B;gBACpC,SAAS,EAAE,eAAe;gBAC1B,CAAC,kBAAkB,CAAC,EAAE,KAAK;aAC5B,CAAC;YACF,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAChD,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC9C,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,iBAAiB;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAA4B;gBACpC,SAAS,EAAE,eAAe;gBAC1B,SAAS,EAAE,eAAe;aAC3B,CAAC;YACF,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Integration tests for the confirmLinkedConfig middleware.\n *\n * The middleware merges the two legacy \"Use linked account?\" / \"Use linked\n * project?\" prompts into a single combined Y/n. CI/CD safety is delegated to\n * the existing isInteractiveTerminal() check used elsewhere in the CLI — these\n * tests verify both the interactive UX and that non-interactive runs skip the\n * prompt entirely.\n */\n/// <reference types=\"jest\" />\nimport { confirmLinkedConfig } from \"../../common/middleware/confirm-linked-config.js\";\nimport {\n confirmLinkedValue,\n readLinkedConfig,\n USE_LINKED_DETAILS,\n} from \"../../common/read-linked-config.js\";\nimport { isInteractiveTerminal } from \"../../common/terminal.js\";\nimport {\n cleanupTest,\n setupTestEnvironment,\n TEST_ACCOUNT_NAME,\n TEST_AUTH_TOKEN,\n TEST_PROJECT_NAME,\n} from \"./test-utils.js\";\n\njest.mock(\"../../common/read-linked-config.js\", () => ({\n __esModule: true,\n confirmLinkedValue: jest.fn().mockResolvedValue(true),\n readLinkedConfig: jest.fn().mockResolvedValue({}),\n USE_LINKED_DETAILS: \"useLinkedDetails\",\n ignoreLinkedDetails: jest\n .fn()\n .mockImplementation((argv: Record<string, unknown>) => {\n argv[\"useLinkedDetails\"] = false;\n }),\n}));\n\njest.mock(\"../../common/terminal.js\", () => ({\n __esModule: true,\n isInteractiveTerminal: jest.fn().mockReturnValue(true),\n}));\n\ndescribe(\"confirmLinkedConfig middleware\", () => {\n beforeEach(() => {\n setupTestEnvironment();\n jest.clearAllMocks();\n jest.mocked(isInteractiveTerminal).mockReturnValue(true);\n jest.mocked(confirmLinkedValue).mockResolvedValue(true);\n jest.mocked(readLinkedConfig).mockResolvedValue({});\n });\n\n afterEach(() => {\n cleanupTest();\n });\n\n describe(\"when both account and project are linked and the terminal is interactive\", () => {\n it(\"asks a single combined Y/n prompt and sets both values on accept\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n jest.mocked(confirmLinkedValue).mockResolvedValue(true);\n\n const argv: Record<string, unknown> = { authToken: TEST_AUTH_TOKEN };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).toHaveBeenCalledTimes(1);\n expect(confirmLinkedValue).toHaveBeenCalledWith(\n `Use linked project '${TEST_PROJECT_NAME}' in account '${TEST_ACCOUNT_NAME}'?`\n );\n expect(argv.account).toBe(TEST_ACCOUNT_NAME);\n expect(argv.project).toBe(TEST_PROJECT_NAME);\n expect(argv[USE_LINKED_DETAILS]).not.toBe(false);\n });\n\n it(\"sets useLinkedDetails=false on decline so downstream pickers run\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n jest.mocked(confirmLinkedValue).mockResolvedValue(false);\n\n const argv: Record<string, unknown> = { authToken: TEST_AUTH_TOKEN };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).toHaveBeenCalledTimes(1);\n expect(argv[USE_LINKED_DETAILS]).toBe(false);\n expect(argv.account).toBeUndefined();\n expect(argv.project).toBeUndefined();\n });\n });\n\n describe(\"when the terminal is non-interactive (CI/CD)\", () => {\n it(\"silently uses both linked values without prompting\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n jest.mocked(isInteractiveTerminal).mockReturnValue(false);\n\n const argv: Record<string, unknown> = { authToken: TEST_AUTH_TOKEN };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(argv.account).toBe(TEST_ACCOUNT_NAME);\n expect(argv.project).toBe(TEST_PROJECT_NAME);\n });\n });\n\n describe(\"when one of --account or --project is already supplied\", () => {\n it(\"skips entirely when --account is supplied (defers to fetchProject)\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n\n const argv: Record<string, unknown> = {\n authToken: TEST_AUTH_TOKEN,\n account: \"explicit-account\",\n };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(readLinkedConfig).not.toHaveBeenCalled();\n expect(argv.account).toBe(\"explicit-account\");\n expect(argv.project).toBeUndefined();\n });\n\n it(\"skips entirely when --project is supplied (defers to fetchAccount)\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n\n const argv: Record<string, unknown> = {\n authToken: TEST_AUTH_TOKEN,\n project: \"explicit-project\",\n };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(readLinkedConfig).not.toHaveBeenCalled();\n expect(argv.project).toBe(\"explicit-project\");\n expect(argv.account).toBeUndefined();\n });\n\n it(\"skips entirely when both flags are supplied\", async () => {\n const argv: Record<string, unknown> = {\n authToken: TEST_AUTH_TOKEN,\n account: \"explicit-account\",\n project: \"explicit-project\",\n };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(readLinkedConfig).not.toHaveBeenCalled();\n });\n\n it(\"skips entirely when --account is supplied as an array (repeated flag)\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n\n const argv: Record<string, unknown> = {\n authToken: TEST_AUTH_TOKEN,\n account: [\"a\", \"b\"],\n };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(readLinkedConfig).not.toHaveBeenCalled();\n expect(argv.account).toEqual([\"a\", \"b\"]);\n });\n });\n\n describe(\"when --no-prompt is set (argv.prompt === false)\", () => {\n it(\"auto-accepts both linked values without prompting\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n\n const argv: Record<string, unknown> = {\n authToken: TEST_AUTH_TOKEN,\n prompt: false,\n };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(argv.account).toBe(TEST_ACCOUNT_NAME);\n expect(argv.project).toBe(TEST_PROJECT_NAME);\n });\n });\n\n describe(\"when the linked config is partial\", () => {\n it(\"skips when only the account is linked (defers to fetchAccount's single prompt)\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n });\n\n const argv: Record<string, unknown> = { authToken: TEST_AUTH_TOKEN };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(argv.account).toBeUndefined();\n expect(argv.project).toBeUndefined();\n });\n\n it(\"skips when only the project is linked\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n projectName: TEST_PROJECT_NAME,\n });\n\n const argv: Record<string, unknown> = { authToken: TEST_AUTH_TOKEN };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(argv.account).toBeUndefined();\n expect(argv.project).toBeUndefined();\n });\n\n it(\"skips when no linked config exists\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({});\n\n const argv: Record<string, unknown> = { authToken: TEST_AUTH_TOKEN };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n });\n });\n\n describe(\"when useLinkedDetails is already false (link command path)\", () => {\n it(\"skips entirely without reading linked config\", async () => {\n const argv: Record<string, unknown> = {\n authToken: TEST_AUTH_TOKEN,\n [USE_LINKED_DETAILS]: false,\n };\n await confirmLinkedConfig(argv);\n\n expect(readLinkedConfig).not.toHaveBeenCalled();\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(argv[USE_LINKED_DETAILS]).toBe(false);\n });\n });\n\n describe(\"when an api-key is supplied\", () => {\n it(\"skips entirely (account is resolved via the api-key)\", async () => {\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n\n const argv: Record<string, unknown> = {\n authToken: TEST_AUTH_TOKEN,\n \"api-key\": \"zpka_some_key\",\n };\n await confirmLinkedConfig(argv);\n\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n expect(readLinkedConfig).not.toHaveBeenCalled();\n });\n });\n});\n"]}
@@ -57,7 +57,7 @@ describe("Info Command Integration Tests", () => {
57
57
  readLinkedConfig.mockResolvedValue({
58
58
  accountName: TEST_ACCOUNT,
59
59
  projectName: TEST_PROJECT,
60
- environmentType: "working_copy",
60
+ environmentType: "development",
61
61
  });
62
62
  setupAuthenticatedNock(nock(TEST_API_BASE))
63
63
  .get(`/v1/projects`)
@@ -77,9 +77,56 @@ describe("Info Command Integration Tests", () => {
77
77
  expect(output).toContain(`Project: ${TEST_PROJECT}`);
78
78
  expect(output).toContain(`Account: ${TEST_ACCOUNT}`);
79
79
  expect(output).toContain(`Portal: https://portal.zuplo.com/${TEST_ACCOUNT}/${TEST_PROJECT}`);
80
- expect(output).toContain("Environment Type: working_copy");
80
+ expect(output).toContain("Environment Type: working-copy");
81
+ expect(output).not.toContain("Environment Type: development");
81
82
  expect(output).toContain("Source Control: https://github.com/josh-twist/josh-poc");
82
83
  });
84
+ it.each(["development", "working_copy", "working-copy"])("should display 'working-copy' label for ZUPLO_ENVIRONMENT_TYPE=%s", async (envType) => {
85
+ readLinkedConfig.mockResolvedValue({
86
+ accountName: TEST_ACCOUNT,
87
+ projectName: TEST_PROJECT,
88
+ environmentType: envType,
89
+ });
90
+ setupAuthenticatedNock(nock(TEST_API_BASE))
91
+ .get(`/v1/projects`)
92
+ .query({ accountName: TEST_ACCOUNT })
93
+ .reply(200, {
94
+ data: [
95
+ {
96
+ name: TEST_PROJECT,
97
+ sourceRepoUrl: null,
98
+ sourceControlProvider: "NONE",
99
+ },
100
+ ],
101
+ });
102
+ await executeInfoCommand({ "api-key": TEST_AUTH_TOKEN });
103
+ expect(mockPrintResult).toHaveBeenCalledTimes(1);
104
+ const output = mockPrintResult.mock.calls[0][0];
105
+ expect(output).toContain("Environment Type: working-copy");
106
+ });
107
+ it("should omit environment type when the linked value is whitespace-only", async () => {
108
+ readLinkedConfig.mockResolvedValue({
109
+ accountName: TEST_ACCOUNT,
110
+ projectName: TEST_PROJECT,
111
+ environmentType: " ",
112
+ });
113
+ setupAuthenticatedNock(nock(TEST_API_BASE))
114
+ .get(`/v1/projects`)
115
+ .query({ accountName: TEST_ACCOUNT })
116
+ .reply(200, {
117
+ data: [
118
+ {
119
+ name: TEST_PROJECT,
120
+ sourceRepoUrl: null,
121
+ sourceControlProvider: "NONE",
122
+ },
123
+ ],
124
+ });
125
+ await executeInfoCommand({ "api-key": TEST_AUTH_TOKEN });
126
+ expect(mockPrintResult).toHaveBeenCalledTimes(1);
127
+ const output = mockPrintResult.mock.calls[0][0];
128
+ expect(output).not.toContain("Environment Type:");
129
+ });
83
130
  it("should show source control deep link when no repo is connected", async () => {
84
131
  readLinkedConfig.mockResolvedValue({
85
132
  accountName: TEST_ACCOUNT,
@@ -1 +1 @@
1
- {"version":3,"file":"info.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/info.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the info command\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport infoCommand from \"../../cmds/info.js\";\nimport {\n cleanupTest,\n setupAuthenticatedNock,\n setupTestEnvironment,\n TEST_ACCOUNT_NAME,\n TEST_API_BASE,\n TEST_AUTH_TOKEN,\n TEST_PROJECT_NAME,\n} from \"./test-utils.js\";\n\nconst TEST_ACCOUNT = TEST_ACCOUNT_NAME;\nconst TEST_PROJECT = TEST_PROJECT_NAME;\n\njest.mock(\"../../common/read-linked-config.js\", () => ({\n __esModule: true,\n readLinkedConfig: jest.fn().mockResolvedValue({}),\n confirmLinkedValue: jest.fn().mockResolvedValue(true),\n USE_LINKED_DETAILS: \"useLinkedDetails\",\n ignoreLinkedDetails: jest.fn(),\n}));\n\nconst { readLinkedConfig } = jest.requireMock(\n \"../../common/read-linked-config.js\"\n) as { readLinkedConfig: jest.Mock };\n\nasync function executeInfoCommand(args: { \"api-key\"?: string }) {\n const yargsInstance = yargs([])\n .command(infoCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n const commandArgs = [\"info\"];\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n return await yargsInstance.parse(commandArgs);\n}\n\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintCriticalFailure = jest.mocked(\n require(\"../../common/output.js\").printCriticalFailureToConsoleAndExit\n);\nconst mockPrintWarning = jest.mocked(\n require(\"../../common/output.js\").printWarningToConsole\n);\n\ndescribe(\"Info Command Integration Tests\", () => {\n beforeEach(() => {\n setupTestEnvironment();\n nock.cleanAll();\n nock.disableNetConnect();\n jest.clearAllMocks();\n readLinkedConfig.mockResolvedValue({});\n });\n\n afterEach(() => {\n cleanupTest();\n });\n\n it(\"should show 'no project linked' when .env.zuplo is missing\", async () => {\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(\"No project linked\");\n expect(output).toContain(\"zuplo link\");\n });\n\n it(\"should show 'no project linked' when unauthenticated and not linked\", async () => {\n await executeInfoCommand({});\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(\"No project linked\");\n expect(output).toContain(\"zuplo link\");\n expect(mockPrintCriticalFailure).not.toHaveBeenCalled();\n });\n\n it(\"should show full project info when linked\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"working_copy\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: \"https://github.com/josh-twist/josh-poc\",\n sourceControlProvider: \"GITHUB\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).toContain(\n `Portal: https://portal.zuplo.com/${TEST_ACCOUNT}/${TEST_PROJECT}`\n );\n expect(output).toContain(\"Environment Type: working_copy\");\n expect(output).toContain(\n \"Source Control: https://github.com/josh-twist/josh-poc\"\n );\n });\n\n it(\"should show source control deep link when no repo is connected\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"production\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: null,\n sourceControlProvider: \"NONE\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(\n `Source Control: none, connect at https://portal.zuplo.com/${TEST_ACCOUNT}/${TEST_PROJECT}/settings/source-control-settings`\n );\n });\n\n it(\"should omit environment type when not in linked config\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: null,\n sourceControlProvider: \"NONE\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).not.toContain(\"Environment Type:\");\n });\n\n it(\"should exit with error when API returns 401 and --api-key was used\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(401, {\n type: \"https://httpproblems.com/http-status/401\",\n title: \"Unauthorized\",\n status: 401,\n detail: \"Invalid token\",\n });\n\n await expect(\n executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(mockPrintCriticalFailure).toHaveBeenCalledWith(\n \"The provided --api-key was rejected. Check that it is valid and not expired, or run `zuplo login` to authenticate interactively.\"\n );\n expect(mockPrintResult).not.toHaveBeenCalled();\n expect(mockPrintWarning).not.toHaveBeenCalled();\n });\n\n it(\"should exit with error when API returns 401 and saved credentials were used\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(401, {\n type: \"https://httpproblems.com/http-status/401\",\n title: \"Unauthorized\",\n status: 401,\n detail: \"Invalid token\",\n });\n\n await expect(executeInfoCommand({})).rejects.toThrow(\"Process would exit\");\n\n expect(mockPrintCriticalFailure).toHaveBeenCalledWith(\n \"Your saved credentials were rejected. They may be expired — run `zuplo login` to re-authenticate, or pass a valid --api-key.\"\n );\n expect(mockPrintResult).not.toHaveBeenCalled();\n expect(mockPrintWarning).not.toHaveBeenCalled();\n });\n\n it(\"should show local info with warning when API returns a server error\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(500, { error: \"Internal Server Error\" });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).not.toContain(\"Source Control:\");\n expect(mockPrintWarning).toHaveBeenCalledWith(\n \"Unable to fetch project details, some information may be missing\"\n );\n });\n\n it(\"should exit with error when API returns a non-401 4xx\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(403, { error: \"Forbidden\" });\n\n await expect(\n executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(mockPrintCriticalFailure).toHaveBeenCalledWith(\n `The Zuplo API returned 403 Forbidden. Verify the account \"${TEST_ACCOUNT}\" and your credentials.`\n );\n expect(mockPrintResult).not.toHaveBeenCalled();\n expect(mockPrintWarning).not.toHaveBeenCalled();\n });\n\n it(\"should show local info with warning on network error\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .replyWithError(\"ECONNREFUSED\");\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).not.toContain(\"Source Control:\");\n expect(mockPrintWarning).toHaveBeenCalledWith(\n \"Unable to fetch project details, some information may be missing\"\n );\n });\n\n it(\"should warn and omit source control when linked project is not in API response\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"working_copy\",\n });\n\n // API returns projects but none match the linked project name (stale .env.zuplo)\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: \"some-other-project\",\n sourceRepoUrl: \"https://github.com/josh-twist/other\",\n sourceControlProvider: \"GITHUB\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).not.toContain(\"Source Control:\");\n expect(mockPrintWarning).toHaveBeenCalledWith(\n `Project \"${TEST_PROJECT}\" was not found in account \"${TEST_ACCOUNT}\". Run \\`zuplo link\\` to link a project.`\n );\n });\n});\n"]}
1
+ {"version":3,"file":"info.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/info.integration.test.ts"],"names":[],"mappings":"AAIA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,aAAa,CAAC;AAChC,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,YAAY,GAAG,iBAAiB,CAAC;AACvC,MAAM,YAAY,GAAG,iBAAiB,CAAC;AAEvC,IAAI,CAAC,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,UAAU,EAAE,IAAI;IAChB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACjD,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC;IACrD,kBAAkB,EAAE,kBAAkB;IACtC,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;CAC/B,CAAC,CAAC,CAAC;AAEJ,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,WAAW,CAC3C,oCAAoC,CACF,CAAC;AAErC,KAAK,UAAU,kBAAkB,CAAC,IAA4B;IAC5D,MAAM,aAAa,GAAG,KAAK,CAAC,EAAE,CAAC;SAC5B,OAAO,CAAC,WAAW,CAAC;SACpB,IAAI,CAAC,KAAK,CAAC;SACX,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,KAAK,CAAC,CAAC;IAEtB,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC;IAE7B,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,MAAM,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CACjC,OAAO,CAAC,wBAAwB,CAAC,CAAC,qCAAqC,CACxE,CAAC;AACF,MAAM,wBAAwB,GAAG,IAAI,CAAC,MAAM,CAC1C,OAAO,CAAC,wBAAwB,CAAC,CAAC,oCAAoC,CACvE,CAAC;AACF,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAClC,OAAO,CAAC,wBAAwB,CAAC,CAAC,qBAAqB,CACxD,CAAC;AAEF,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,UAAU,CAAC,GAAG,EAAE;QACd,oBAAoB,EAAE,CAAC;QACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,gBAAgB,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAE7B,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,wBAAwB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QAIzD,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,aAAa;SAC/B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,YAAY;oBAClB,aAAa,EAAE,wCAAwC;oBACvD,qBAAqB,EAAE,QAAQ;iBAChC;aACF;SACF,CAAC,CAAC;QAEL,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CACtB,oCAAoC,YAAY,IAAI,YAAY,EAAE,CACnE,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CACtB,wDAAwD,CACzD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC,CACtD,mEAAmE,EACnE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChB,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,OAAO;SACzB,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,YAAY;oBAClB,aAAa,EAAE,IAAI;oBACnB,qBAAqB,EAAE,MAAM;iBAC9B;aACF;SACF,CAAC,CAAC;QAEL,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,YAAY;oBAClB,aAAa,EAAE,IAAI;oBACnB,qBAAqB,EAAE,MAAM;iBAC9B;aACF;SACF,CAAC,CAAC;QAEL,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,YAAY;SAC9B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,YAAY;oBAClB,aAAa,EAAE,IAAI;oBACnB,qBAAqB,EAAE,MAAM;iBAC9B;aACF;SACF,CAAC,CAAC;QAEL,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CACtB,6DAA6D,YAAY,IAAI,YAAY,mCAAmC,CAC7H,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;SAC1B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,YAAY;oBAClB,aAAa,EAAE,IAAI;oBACnB,qBAAqB,EAAE,MAAM;iBAC9B;aACF;SACF,CAAC,CAAC;QAEL,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,aAAa;SAC/B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE,0CAA0C;YAChD,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,GAAG;YACX,MAAM,EAAE,eAAe;SACxB,CAAC,CAAC;QAEL,MAAM,MAAM,CACV,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CACnD,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAExC,MAAM,CAAC,wBAAwB,CAAC,CAAC,oBAAoB,CACnD,kIAAkI,CACnI,CAAC;QACF,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;QAC3F,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,aAAa;SAC/B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE,0CAA0C;YAChD,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,GAAG;YACX,MAAM,EAAE,eAAe;SACxB,CAAC,CAAC;QAEL,MAAM,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAE3E,MAAM,CAAC,wBAAwB,CAAC,CAAC,oBAAoB,CACnD,8HAA8H,CAC/H,CAAC;QACF,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,aAAa;SAC/B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;QAElD,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,kEAAkE,CACnE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,aAAa;SAC/B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAEtC,MAAM,MAAM,CACV,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CACnD,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAExC,MAAM,CAAC,wBAAwB,CAAC,CAAC,oBAAoB,CACnD,6DAA6D,YAAY,yBAAyB,CACnG,CAAC;QACF,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,aAAa;SAC/B,CAAC,CAAC;QAEH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,cAAc,CAAC,cAAc,CAAC,CAAC;QAElC,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,kEAAkE,CACnE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,YAAY;YACzB,eAAe,EAAE,cAAc;SAChC,CAAC,CAAC;QAGH,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACxC,GAAG,CAAC,cAAc,CAAC;aACnB,KAAK,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;aACpC,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,oBAAoB;oBAC1B,aAAa,EAAE,qCAAqC;oBACpD,qBAAqB,EAAE,QAAQ;iBAChC;aACF;SACF,CAAC,CAAC;QAEL,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAC3C,YAAY,YAAY,+BAA+B,YAAY,0CAA0C,CAC9G,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Integration tests for the info command\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport infoCommand from \"../../cmds/info.js\";\nimport {\n cleanupTest,\n setupAuthenticatedNock,\n setupTestEnvironment,\n TEST_ACCOUNT_NAME,\n TEST_API_BASE,\n TEST_AUTH_TOKEN,\n TEST_PROJECT_NAME,\n} from \"./test-utils.js\";\n\nconst TEST_ACCOUNT = TEST_ACCOUNT_NAME;\nconst TEST_PROJECT = TEST_PROJECT_NAME;\n\njest.mock(\"../../common/read-linked-config.js\", () => ({\n __esModule: true,\n readLinkedConfig: jest.fn().mockResolvedValue({}),\n confirmLinkedValue: jest.fn().mockResolvedValue(true),\n USE_LINKED_DETAILS: \"useLinkedDetails\",\n ignoreLinkedDetails: jest.fn(),\n}));\n\nconst { readLinkedConfig } = jest.requireMock(\n \"../../common/read-linked-config.js\"\n) as { readLinkedConfig: jest.Mock };\n\nasync function executeInfoCommand(args: { \"api-key\"?: string }) {\n const yargsInstance = yargs([])\n .command(infoCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n const commandArgs = [\"info\"];\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n return await yargsInstance.parse(commandArgs);\n}\n\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintCriticalFailure = jest.mocked(\n require(\"../../common/output.js\").printCriticalFailureToConsoleAndExit\n);\nconst mockPrintWarning = jest.mocked(\n require(\"../../common/output.js\").printWarningToConsole\n);\n\ndescribe(\"Info Command Integration Tests\", () => {\n beforeEach(() => {\n setupTestEnvironment();\n nock.cleanAll();\n nock.disableNetConnect();\n jest.clearAllMocks();\n readLinkedConfig.mockResolvedValue({});\n });\n\n afterEach(() => {\n cleanupTest();\n });\n\n it(\"should show 'no project linked' when .env.zuplo is missing\", async () => {\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(\"No project linked\");\n expect(output).toContain(\"zuplo link\");\n });\n\n it(\"should show 'no project linked' when unauthenticated and not linked\", async () => {\n await executeInfoCommand({});\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(\"No project linked\");\n expect(output).toContain(\"zuplo link\");\n expect(mockPrintCriticalFailure).not.toHaveBeenCalled();\n });\n\n it(\"should show full project info when linked\", async () => {\n // The tenant API emits \"development\" for working-copy environments, which\n // is what gets written into .env.zuplo. The CLI must display this as\n // \"working-copy\".\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: \"https://github.com/josh-twist/josh-poc\",\n sourceControlProvider: \"GITHUB\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).toContain(\n `Portal: https://portal.zuplo.com/${TEST_ACCOUNT}/${TEST_PROJECT}`\n );\n expect(output).toContain(\"Environment Type: working-copy\");\n expect(output).not.toContain(\"Environment Type: development\");\n expect(output).toContain(\n \"Source Control: https://github.com/josh-twist/josh-poc\"\n );\n });\n\n it.each([\"development\", \"working_copy\", \"working-copy\"])(\n \"should display 'working-copy' label for ZUPLO_ENVIRONMENT_TYPE=%s\",\n async (envType) => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: envType,\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: null,\n sourceControlProvider: \"NONE\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(\"Environment Type: working-copy\");\n }\n );\n\n it(\"should omit environment type when the linked value is whitespace-only\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \" \",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: null,\n sourceControlProvider: \"NONE\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).not.toContain(\"Environment Type:\");\n });\n\n it(\"should show source control deep link when no repo is connected\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"production\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: null,\n sourceControlProvider: \"NONE\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(\n `Source Control: none, connect at https://portal.zuplo.com/${TEST_ACCOUNT}/${TEST_PROJECT}/settings/source-control-settings`\n );\n });\n\n it(\"should omit environment type when not in linked config\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: TEST_PROJECT,\n sourceRepoUrl: null,\n sourceControlProvider: \"NONE\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).not.toContain(\"Environment Type:\");\n });\n\n it(\"should exit with error when API returns 401 and --api-key was used\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(401, {\n type: \"https://httpproblems.com/http-status/401\",\n title: \"Unauthorized\",\n status: 401,\n detail: \"Invalid token\",\n });\n\n await expect(\n executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(mockPrintCriticalFailure).toHaveBeenCalledWith(\n \"The provided --api-key was rejected. Check that it is valid and not expired, or run `zuplo login` to authenticate interactively.\"\n );\n expect(mockPrintResult).not.toHaveBeenCalled();\n expect(mockPrintWarning).not.toHaveBeenCalled();\n });\n\n it(\"should exit with error when API returns 401 and saved credentials were used\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(401, {\n type: \"https://httpproblems.com/http-status/401\",\n title: \"Unauthorized\",\n status: 401,\n detail: \"Invalid token\",\n });\n\n await expect(executeInfoCommand({})).rejects.toThrow(\"Process would exit\");\n\n expect(mockPrintCriticalFailure).toHaveBeenCalledWith(\n \"Your saved credentials were rejected. They may be expired — run `zuplo login` to re-authenticate, or pass a valid --api-key.\"\n );\n expect(mockPrintResult).not.toHaveBeenCalled();\n expect(mockPrintWarning).not.toHaveBeenCalled();\n });\n\n it(\"should show local info with warning when API returns a server error\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(500, { error: \"Internal Server Error\" });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).not.toContain(\"Source Control:\");\n expect(mockPrintWarning).toHaveBeenCalledWith(\n \"Unable to fetch project details, some information may be missing\"\n );\n });\n\n it(\"should exit with error when API returns a non-401 4xx\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(403, { error: \"Forbidden\" });\n\n await expect(\n executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(mockPrintCriticalFailure).toHaveBeenCalledWith(\n `The Zuplo API returned 403 Forbidden. Verify the account \"${TEST_ACCOUNT}\" and your credentials.`\n );\n expect(mockPrintResult).not.toHaveBeenCalled();\n expect(mockPrintWarning).not.toHaveBeenCalled();\n });\n\n it(\"should show local info with warning on network error\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"development\",\n });\n\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .replyWithError(\"ECONNREFUSED\");\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).not.toContain(\"Source Control:\");\n expect(mockPrintWarning).toHaveBeenCalledWith(\n \"Unable to fetch project details, some information may be missing\"\n );\n });\n\n it(\"should warn and omit source control when linked project is not in API response\", async () => {\n readLinkedConfig.mockResolvedValue({\n accountName: TEST_ACCOUNT,\n projectName: TEST_PROJECT,\n environmentType: \"working_copy\",\n });\n\n // API returns projects but none match the linked project name (stale .env.zuplo)\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/projects`)\n .query({ accountName: TEST_ACCOUNT })\n .reply(200, {\n data: [\n {\n name: \"some-other-project\",\n sourceRepoUrl: \"https://github.com/josh-twist/other\",\n sourceControlProvider: \"GITHUB\",\n },\n ],\n });\n\n await executeInfoCommand({ \"api-key\": TEST_AUTH_TOKEN });\n\n expect(mockPrintResult).toHaveBeenCalledTimes(1);\n const output = mockPrintResult.mock.calls[0][0] as string;\n expect(output).toContain(`Project: ${TEST_PROJECT}`);\n expect(output).toContain(`Account: ${TEST_ACCOUNT}`);\n expect(output).not.toContain(\"Source Control:\");\n expect(mockPrintWarning).toHaveBeenCalledWith(\n `Project \"${TEST_PROJECT}\" was not found in account \"${TEST_ACCOUNT}\". Run \\`zuplo link\\` to link a project.`\n );\n });\n});\n"]}
@@ -40,16 +40,32 @@ jest.mock("../../common/middleware/authentication.js", () => ({
40
40
  return argv;
41
41
  }),
42
42
  }));
43
- jest.mock("@inquirer/prompts", () => ({
44
- select: jest.fn().mockImplementation(({ choices }) => {
45
- if (Array.isArray(choices) && choices.length > 0) {
46
- const firstReal = choices.find((c) => c.value !== null) ?? choices[0];
47
- return Promise.resolve(firstReal.value);
43
+ jest.mock("@inquirer/prompts", () => {
44
+ class MockSeparator {
45
+ type = "separator";
46
+ separator;
47
+ constructor(separator = "──────────────") {
48
+ this.separator = separator;
48
49
  }
49
- return Promise.resolve("test-default");
50
- }),
51
- input: jest.fn().mockResolvedValue("test-new-project"),
52
- }));
50
+ static isSeparator(item) {
51
+ return (item != null &&
52
+ typeof item === "object" &&
53
+ item.type === "separator");
54
+ }
55
+ }
56
+ return {
57
+ Separator: MockSeparator,
58
+ select: jest.fn().mockImplementation(({ choices }) => {
59
+ if (Array.isArray(choices) && choices.length > 0) {
60
+ const firstReal = choices.find((c) => !MockSeparator.isSeparator(c) &&
61
+ c.value !== null) ?? choices[0];
62
+ return Promise.resolve(firstReal.value);
63
+ }
64
+ return Promise.resolve("test-default");
65
+ }),
66
+ input: jest.fn().mockResolvedValue("test-new-project"),
67
+ };
68
+ });
53
69
  jest.mock("../../common/middleware/user-configuration.js", () => ({
54
70
  configure: jest.fn((argv) => argv),
55
71
  }));
@@ -62,7 +78,10 @@ jest.mock("../../common/validators/lib.js", () => ({
62
78
  })),
63
79
  }));
64
80
  jest.mock("../../common/handler.js", () => ({
65
- groupHandler: jest.fn(),
81
+ showHelpOnNoSubcommand: jest.fn((configure) => ({
82
+ builder: (yargs) => configure(yargs),
83
+ handler: jest.fn(),
84
+ })),
66
85
  }));
67
86
  jest.mock("../../login/tokens.js", () => ({
68
87
  getAuthToken: jest.fn().mockResolvedValue(TEST_AUTH_TOKEN),
@@ -1 +1 @@
1
- {"version":3,"file":"jest-mocks-setup.js","sourceRoot":"","sources":["../../../src/__tests__/integration/jest-mocks-setup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Jest mocks setup - loaded before all test modules\n * This file contains all the Jest mocks that need to be applied before any modules are imported\n */\nimport type { Ora } from \"ora\";\n\nconst TEST_AUTH_TOKEN = \"test-auth-token-123\";\n\n// Mock all output functions to prevent actual console output and process.exit calls\njest.mock(\"../../common/output.js\", () => ({\n __esModule: true,\n default: jest.fn((argv: unknown) => argv), // setBlocking middleware function\n printResultToConsoleAndExitGracefully: jest.fn().mockResolvedValue(undefined),\n printTableToConsoleAndExitGracefully: jest.fn().mockResolvedValue(undefined),\n printJsonToConsoleAndExitGracefully: jest.fn().mockResolvedValue(undefined),\n printResultToConsole: jest.fn().mockResolvedValue(undefined),\n printJsonToConsole: jest.fn().mockResolvedValue(undefined),\n printDiagnosticsToConsole: jest.fn(),\n printWarningToConsole: jest.fn(),\n printSpinnerToConsole: jest.fn().mockReturnValue({\n stop: jest.fn(),\n succeed: jest.fn(),\n fail: jest.fn(),\n suffixText: \"\",\n } as unknown as Ora),\n printCriticalFailureToConsoleAndExit: jest.fn().mockImplementation(() => {\n throw new Error(\"Process would exit\");\n }),\n textOrJson: jest.fn((text: string) => {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n }),\n}));\n\n// Mock analytics\njest.mock(\"../../common/analytics/lib.js\", () => ({\n captureEvent: jest.fn().mockResolvedValue(undefined),\n}));\n\n// Mock authentication middleware to add authToken\njest.mock(\"../../common/middleware/authentication.js\", () => ({\n authenticate: jest.fn((argv: Record<string, unknown>) => {\n argv.authToken = TEST_AUTH_TOKEN;\n return argv;\n }),\n authenticateNoPrompt: jest.fn((argv: Record<string, unknown>) => {\n argv.authToken = TEST_AUTH_TOKEN;\n return argv;\n }),\n}));\n\n// Mock inquirer prompts to return predictable values for tests\njest.mock(\"@inquirer/prompts\", () => ({\n select: jest.fn().mockImplementation(({ choices }) => {\n if (Array.isArray(choices) && choices.length > 0) {\n // Skip null sentinel values (e.g. \"+ Create a new project\") and return the first real project.\n const firstReal = choices.find((c) => c.value !== null) ?? choices[0];\n return Promise.resolve(firstReal.value);\n }\n return Promise.resolve(\"test-default\");\n }),\n input: jest.fn().mockResolvedValue(\"test-new-project\"),\n}));\n\n// Mock other middleware to pass through arguments\njest.mock(\"../../common/middleware/user-configuration.js\", () => ({\n configure: jest.fn((argv: unknown) => argv),\n}));\n\njest.mock(\"../../common/middleware/user-identification.js\", () => ({\n identify: jest.fn((argv: unknown) => argv),\n}));\n\n// Mock validators to pass through\njest.mock(\"../../common/validators/lib.js\", () => ({\n YargsChecker: jest.fn().mockImplementation(() => ({\n check: jest.fn().mockResolvedValue(true),\n })),\n}));\n\n// Mock group handler for commands with subcommands\njest.mock(\"../../common/handler.js\", () => ({\n groupHandler: jest.fn(),\n}));\n\n// Mock token functions to prevent file system and HTTP calls\njest.mock(\"../../login/tokens.js\", () => ({\n getAuthToken: jest.fn().mockResolvedValue(TEST_AUTH_TOKEN),\n refreshAccessToken: jest.fn().mockResolvedValue({\n access_token: TEST_AUTH_TOKEN,\n id_token: \"mock-id-token\",\n expires_in: 3600,\n token_type: \"Bearer\",\n scope: \"openid profile email\",\n }),\n}));\n"]}
1
+ {"version":3,"file":"jest-mocks-setup.js","sourceRoot":"","sources":["../../../src/__tests__/integration/jest-mocks-setup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Jest mocks setup - loaded before all test modules\n * This file contains all the Jest mocks that need to be applied before any modules are imported\n */\nimport type { Ora } from \"ora\";\n\nconst TEST_AUTH_TOKEN = \"test-auth-token-123\";\n\n// Mock all output functions to prevent actual console output and process.exit calls\njest.mock(\"../../common/output.js\", () => ({\n __esModule: true,\n default: jest.fn((argv: unknown) => argv), // setBlocking middleware function\n printResultToConsoleAndExitGracefully: jest.fn().mockResolvedValue(undefined),\n printTableToConsoleAndExitGracefully: jest.fn().mockResolvedValue(undefined),\n printJsonToConsoleAndExitGracefully: jest.fn().mockResolvedValue(undefined),\n printResultToConsole: jest.fn().mockResolvedValue(undefined),\n printJsonToConsole: jest.fn().mockResolvedValue(undefined),\n printDiagnosticsToConsole: jest.fn(),\n printWarningToConsole: jest.fn(),\n printSpinnerToConsole: jest.fn().mockReturnValue({\n stop: jest.fn(),\n succeed: jest.fn(),\n fail: jest.fn(),\n suffixText: \"\",\n } as unknown as Ora),\n printCriticalFailureToConsoleAndExit: jest.fn().mockImplementation(() => {\n throw new Error(\"Process would exit\");\n }),\n textOrJson: jest.fn((text: string) => {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n }),\n}));\n\n// Mock analytics\njest.mock(\"../../common/analytics/lib.js\", () => ({\n captureEvent: jest.fn().mockResolvedValue(undefined),\n}));\n\n// Mock authentication middleware to add authToken\njest.mock(\"../../common/middleware/authentication.js\", () => ({\n authenticate: jest.fn((argv: Record<string, unknown>) => {\n argv.authToken = TEST_AUTH_TOKEN;\n return argv;\n }),\n authenticateNoPrompt: jest.fn((argv: Record<string, unknown>) => {\n argv.authToken = TEST_AUTH_TOKEN;\n return argv;\n }),\n}));\n\n// Mock inquirer prompts to return predictable values for tests\njest.mock(\"@inquirer/prompts\", () => {\n class MockSeparator {\n type = \"separator\";\n separator: string;\n constructor(separator = \"──────────────\") {\n this.separator = separator;\n }\n static isSeparator(item: unknown): boolean {\n return (\n item != null &&\n typeof item === \"object\" &&\n (item as { type?: unknown }).type === \"separator\"\n );\n }\n }\n return {\n Separator: MockSeparator,\n select: jest.fn().mockImplementation(({ choices }) => {\n if (Array.isArray(choices) && choices.length > 0) {\n // Skip separators (no `value`) and null-sentinel choices, then return\n // the first real choice's value.\n const firstReal =\n choices.find(\n (c) =>\n !MockSeparator.isSeparator(c) &&\n (c as { value?: unknown }).value !== null\n ) ?? choices[0];\n return Promise.resolve((firstReal as { value: unknown }).value);\n }\n return Promise.resolve(\"test-default\");\n }),\n input: jest.fn().mockResolvedValue(\"test-new-project\"),\n };\n});\n\n// Mock other middleware to pass through arguments\njest.mock(\"../../common/middleware/user-configuration.js\", () => ({\n configure: jest.fn((argv: unknown) => argv),\n}));\n\njest.mock(\"../../common/middleware/user-identification.js\", () => ({\n identify: jest.fn((argv: unknown) => argv),\n}));\n\n// Mock validators to pass through\njest.mock(\"../../common/validators/lib.js\", () => ({\n YargsChecker: jest.fn().mockImplementation(() => ({\n check: jest.fn().mockResolvedValue(true),\n })),\n}));\n\n// Mock showHelpOnNoSubcommand helper for commands with subcommands\njest.mock(\"../../common/handler.js\", () => ({\n showHelpOnNoSubcommand: jest.fn((configure) => ({\n builder: (yargs: unknown) => (configure as (y: unknown) => unknown)(yargs),\n handler: jest.fn(),\n })),\n}));\n\n// Mock token functions to prevent file system and HTTP calls\njest.mock(\"../../login/tokens.js\", () => ({\n getAuthToken: jest.fn().mockResolvedValue(TEST_AUTH_TOKEN),\n refreshAccessToken: jest.fn().mockResolvedValue({\n access_token: TEST_AUTH_TOKEN,\n id_token: \"mock-id-token\",\n expires_in: 3600,\n token_type: \"Bearer\",\n scope: \"openid profile email\",\n }),\n}));\n"]}
@@ -1,4 +1,5 @@
1
1
  import nock from "nock";
2
+ import { confirmLinkedConfig } from "../../common/middleware/confirm-linked-config.js";
2
3
  import { fetchAccount } from "../../common/middleware/get-account-param.js";
3
4
  import { fetchEnvironment } from "../../common/middleware/get-environment-param.js";
4
5
  import { fetchProject } from "../../common/middleware/get-project-param.js";
@@ -109,6 +110,41 @@ describe("Linked-config cascade decline", () => {
109
110
  expect(confirmLinkedValue).not.toHaveBeenCalled();
110
111
  expect(argv.project).toBe(TEST_PROJECT_NAME);
111
112
  });
113
+ it("combined prompt accepted: full chain calls confirmLinkedValue exactly once", async () => {
114
+ jest.mocked(readLinkedConfig).mockResolvedValue({
115
+ accountName: TEST_ACCOUNT_NAME,
116
+ projectName: TEST_PROJECT_NAME,
117
+ });
118
+ jest.mocked(confirmLinkedValue).mockResolvedValue(true);
119
+ const argv = { authToken: TEST_AUTH_TOKEN };
120
+ await confirmLinkedConfig(argv);
121
+ await fetchAccount(argv);
122
+ await fetchProject(argv);
123
+ expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
124
+ expect(confirmLinkedValue).toHaveBeenCalledWith(`Use linked project '${TEST_PROJECT_NAME}' in account '${TEST_ACCOUNT_NAME}'?`);
125
+ expect(argv.account).toBe(TEST_ACCOUNT_NAME);
126
+ expect(argv.project).toBe(TEST_PROJECT_NAME);
127
+ });
128
+ it("combined prompt declined: full chain falls through to API pickers without further linked prompts", async () => {
129
+ jest.mocked(readLinkedConfig).mockResolvedValue({
130
+ accountName: TEST_ACCOUNT_NAME,
131
+ projectName: TEST_PROJECT_NAME,
132
+ });
133
+ jest.mocked(confirmLinkedValue).mockResolvedValue(false);
134
+ setupAuthenticatedNock(nock(TEST_API_BASE))
135
+ .get("/v1/accounts")
136
+ .reply(200, { data: [{ name: TEST_ACCOUNT_NAME }] });
137
+ setupAuthenticatedNock(nock(TEST_API_BASE))
138
+ .get("/v1/projects")
139
+ .query({ accountName: TEST_ACCOUNT_NAME })
140
+ .reply(200, { data: [{ name: TEST_PROJECT_NAME }] });
141
+ const argv = { authToken: TEST_AUTH_TOKEN };
142
+ await confirmLinkedConfig(argv);
143
+ await fetchAccount(argv);
144
+ await fetchProject(argv);
145
+ expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
146
+ expect(argv[USE_LINKED_DETAILS]).toBe(false);
147
+ });
112
148
  it("fails loudly when --project is omitted in non-interactive environments without linked config", async () => {
113
149
  jest.mocked(readLinkedConfig).mockResolvedValue({});
114
150
  jest.mocked(isInteractiveTerminal).mockReturnValue(false);