@zuplo/cli 7.10.0 → 7.11.1

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 (310) hide show
  1. package/dist/common/worker-output.d.ts +7 -0
  2. package/dist/common/worker-output.d.ts.map +1 -1
  3. package/dist/common/worker-output.js +39 -0
  4. package/dist/common/worker-output.js.map +1 -1
  5. package/dist/tsconfig.tsbuildinfo +1 -1
  6. package/node_modules/@hono/node-server/README.md +2 -0
  7. package/node_modules/@hono/node-server/dist/index.cjs +1 -1
  8. package/node_modules/@hono/node-server/dist/index.mjs +1 -1
  9. package/node_modules/@hono/node-server/dist/serve-static.cjs +2 -1
  10. package/node_modules/@hono/node-server/dist/serve-static.mjs +2 -1
  11. package/node_modules/@hono/node-server/package.json +1 -1
  12. package/node_modules/@posthog/core/dist/metrics/index.d.ts +9 -0
  13. package/node_modules/@posthog/core/dist/metrics/index.d.ts.map +1 -1
  14. package/node_modules/@posthog/core/dist/metrics/index.js +38 -3
  15. package/node_modules/@posthog/core/dist/metrics/index.mjs +38 -3
  16. package/node_modules/@posthog/core/dist/metrics/types.d.ts +7 -2
  17. package/node_modules/@posthog/core/dist/metrics/types.d.ts.map +1 -1
  18. package/node_modules/@posthog/core/dist/traces/ids.d.ts.map +1 -1
  19. package/node_modules/@posthog/core/dist/traces/ids.js +2 -2
  20. package/node_modules/@posthog/core/dist/traces/ids.mjs +2 -2
  21. package/node_modules/@posthog/core/dist/types.d.ts +1 -1
  22. package/node_modules/@posthog/core/dist/types.d.ts.map +1 -1
  23. package/node_modules/@posthog/core/package.json +4 -3
  24. package/node_modules/@posthog/core/src/metrics/index.spec.ts +75 -0
  25. package/node_modules/@posthog/core/src/metrics/index.ts +60 -0
  26. package/node_modules/@posthog/core/src/metrics/types.ts +7 -1
  27. package/node_modules/@posthog/core/src/traces/ids.ts +4 -2
  28. package/node_modules/@posthog/core/src/types.ts +1 -1
  29. package/node_modules/@posthog/types/dist/capture-metric.d.ts +10 -0
  30. package/node_modules/@posthog/types/dist/capture-metric.d.ts.map +1 -1
  31. package/node_modules/@posthog/types/dist/capture.d.ts +1 -1
  32. package/node_modules/@posthog/types/dist/capture.d.ts.map +1 -1
  33. package/node_modules/@posthog/types/dist/index.d.ts +1 -1
  34. package/node_modules/@posthog/types/dist/index.d.ts.map +1 -1
  35. package/node_modules/@posthog/types/package.json +1 -1
  36. package/node_modules/@posthog/types/src/capture-metric.ts +11 -0
  37. package/node_modules/@posthog/types/src/capture.ts +1 -1
  38. package/node_modules/@posthog/types/src/index.ts +1 -0
  39. package/node_modules/@zuplo/core/customer.cli.minified.js +272 -261
  40. package/node_modules/@zuplo/core/index.minified.js +276 -265
  41. package/node_modules/@zuplo/core/package.json +1 -1
  42. package/node_modules/@zuplo/graphql/package.json +1 -1
  43. package/node_modules/@zuplo/openapi-tools/package.json +5 -2
  44. package/node_modules/@zuplo/otel/package.json +1 -1
  45. package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js → chunk-CDEAY3VY.js} +2 -2
  46. package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js +37 -0
  47. package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js.map +1 -0
  48. package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js → chunk-NUVXDVLJ.js} +2 -2
  49. package/node_modules/@zuplo/runtime/out/esm/{chunk-6YPRGG62.js → chunk-RHU3Z7DA.js} +108 -108
  50. package/node_modules/@zuplo/runtime/out/esm/chunk-RHU3Z7DA.js.map +1 -0
  51. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  52. package/node_modules/@zuplo/runtime/out/esm/internal/index.js +1 -1
  53. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  54. package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
  55. package/node_modules/@zuplo/runtime/out/esm/sdks/aws/index.js +1 -1
  56. package/node_modules/@zuplo/runtime/out/types/index.d.ts +15 -24
  57. package/node_modules/@zuplo/runtime/out/types/internal/index.d.ts +14 -0
  58. package/node_modules/@zuplo/runtime/package.json +1 -1
  59. package/package.json +15 -12
  60. package/dist/__tests__/archive-utils.test.d.ts +0 -2
  61. package/dist/__tests__/archive-utils.test.d.ts.map +0 -1
  62. package/dist/__tests__/archive-utils.test.js +0 -50
  63. package/dist/__tests__/archive-utils.test.js.map +0 -1
  64. package/dist/__tests__/import-openapi.test.d.ts +0 -2
  65. package/dist/__tests__/import-openapi.test.d.ts.map +0 -1
  66. package/dist/__tests__/import-openapi.test.js +0 -251
  67. package/dist/__tests__/import-openapi.test.js.map +0 -1
  68. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts +0 -2
  69. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts.map +0 -1
  70. package/dist/__tests__/integration/confirm-linked-config.integration.test.js +0 -202
  71. package/dist/__tests__/integration/confirm-linked-config.integration.test.js.map +0 -1
  72. package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts +0 -2
  73. package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts.map +0 -1
  74. package/dist/__tests__/integration/confirm-production-deploy.integration.test.js +0 -184
  75. package/dist/__tests__/integration/confirm-production-deploy.integration.test.js.map +0 -1
  76. package/dist/__tests__/integration/custom-domain.integration.test.d.ts +0 -2
  77. package/dist/__tests__/integration/custom-domain.integration.test.d.ts.map +0 -1
  78. package/dist/__tests__/integration/custom-domain.integration.test.js +0 -563
  79. package/dist/__tests__/integration/custom-domain.integration.test.js.map +0 -1
  80. package/dist/__tests__/integration/delete.integration.test.d.ts +0 -2
  81. package/dist/__tests__/integration/delete.integration.test.d.ts.map +0 -1
  82. package/dist/__tests__/integration/delete.integration.test.js +0 -262
  83. package/dist/__tests__/integration/delete.integration.test.js.map +0 -1
  84. package/dist/__tests__/integration/deploy.integration.test.d.ts +0 -2
  85. package/dist/__tests__/integration/deploy.integration.test.d.ts.map +0 -1
  86. package/dist/__tests__/integration/deploy.integration.test.js +0 -519
  87. package/dist/__tests__/integration/deploy.integration.test.js.map +0 -1
  88. package/dist/__tests__/integration/get-project-param.integration.test.d.ts +0 -2
  89. package/dist/__tests__/integration/get-project-param.integration.test.d.ts.map +0 -1
  90. package/dist/__tests__/integration/get-project-param.integration.test.js +0 -305
  91. package/dist/__tests__/integration/get-project-param.integration.test.js.map +0 -1
  92. package/dist/__tests__/integration/info.integration.test.d.ts +0 -2
  93. package/dist/__tests__/integration/info.integration.test.d.ts.map +0 -1
  94. package/dist/__tests__/integration/info.integration.test.js +0 -293
  95. package/dist/__tests__/integration/info.integration.test.js.map +0 -1
  96. package/dist/__tests__/integration/jest-mocks-setup.d.ts +0 -2
  97. package/dist/__tests__/integration/jest-mocks-setup.d.ts.map +0 -1
  98. package/dist/__tests__/integration/jest-mocks-setup.js +0 -104
  99. package/dist/__tests__/integration/jest-mocks-setup.js.map +0 -1
  100. package/dist/__tests__/integration/jest-setup.d.ts +0 -2
  101. package/dist/__tests__/integration/jest-setup.d.ts.map +0 -1
  102. package/dist/__tests__/integration/jest-setup.js +0 -12
  103. package/dist/__tests__/integration/jest-setup.js.map +0 -1
  104. package/dist/__tests__/integration/link.integration.test.d.ts +0 -2
  105. package/dist/__tests__/integration/link.integration.test.d.ts.map +0 -1
  106. package/dist/__tests__/integration/link.integration.test.js +0 -395
  107. package/dist/__tests__/integration/link.integration.test.js.map +0 -1
  108. package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts +0 -2
  109. package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts.map +0 -1
  110. package/dist/__tests__/integration/linked-config-cascade.integration.test.js +0 -179
  111. package/dist/__tests__/integration/linked-config-cascade.integration.test.js.map +0 -1
  112. package/dist/__tests__/integration/list.integration.test.d.ts +0 -2
  113. package/dist/__tests__/integration/list.integration.test.d.ts.map +0 -1
  114. package/dist/__tests__/integration/list.integration.test.js +0 -300
  115. package/dist/__tests__/integration/list.integration.test.js.map +0 -1
  116. package/dist/__tests__/integration/source-upgrade.integration.test.d.ts +0 -2
  117. package/dist/__tests__/integration/source-upgrade.integration.test.d.ts.map +0 -1
  118. package/dist/__tests__/integration/source-upgrade.integration.test.js +0 -100
  119. package/dist/__tests__/integration/source-upgrade.integration.test.js.map +0 -1
  120. package/dist/__tests__/integration/test-utils.d.ts +0 -30
  121. package/dist/__tests__/integration/test-utils.d.ts.map +0 -1
  122. package/dist/__tests__/integration/test-utils.js +0 -82
  123. package/dist/__tests__/integration/test-utils.js.map +0 -1
  124. package/dist/__tests__/integration/tunnel.integration.test.d.ts +0 -2
  125. package/dist/__tests__/integration/tunnel.integration.test.d.ts.map +0 -1
  126. package/dist/__tests__/integration/tunnel.integration.test.js +0 -486
  127. package/dist/__tests__/integration/tunnel.integration.test.js.map +0 -1
  128. package/dist/__tests__/integration/variable.integration.test.d.ts +0 -2
  129. package/dist/__tests__/integration/variable.integration.test.d.ts.map +0 -1
  130. package/dist/__tests__/integration/variable.integration.test.js +0 -258
  131. package/dist/__tests__/integration/variable.integration.test.js.map +0 -1
  132. package/dist/__tests__/integration/whoami.integration.test.d.ts +0 -2
  133. package/dist/__tests__/integration/whoami.integration.test.d.ts.map +0 -1
  134. package/dist/__tests__/integration/whoami.integration.test.js +0 -116
  135. package/dist/__tests__/integration/whoami.integration.test.js.map +0 -1
  136. package/dist/__tests__/outdated.test.d.ts +0 -2
  137. package/dist/__tests__/outdated.test.d.ts.map +0 -1
  138. package/dist/__tests__/outdated.test.js +0 -67
  139. package/dist/__tests__/outdated.test.js.map +0 -1
  140. package/dist/__tests__/populate.test.d.ts +0 -2
  141. package/dist/__tests__/populate.test.d.ts.map +0 -1
  142. package/dist/__tests__/populate.test.js +0 -445
  143. package/dist/__tests__/populate.test.js.map +0 -1
  144. package/dist/__tests__/tsconfig-upgrader.test.d.ts +0 -2
  145. package/dist/__tests__/tsconfig-upgrader.test.d.ts.map +0 -1
  146. package/dist/__tests__/tsconfig-upgrader.test.js +0 -31
  147. package/dist/__tests__/tsconfig-upgrader.test.js.map +0 -1
  148. package/dist/ca-certificate/validation.test.d.ts +0 -2
  149. package/dist/ca-certificate/validation.test.d.ts.map +0 -1
  150. package/dist/ca-certificate/validation.test.js +0 -131
  151. package/dist/ca-certificate/validation.test.js.map +0 -1
  152. package/dist/common/analytics/cli-invocation.test.d.ts +0 -2
  153. package/dist/common/analytics/cli-invocation.test.d.ts.map +0 -1
  154. package/dist/common/analytics/cli-invocation.test.js +0 -51
  155. package/dist/common/analytics/cli-invocation.test.js.map +0 -1
  156. package/dist/common/analytics/package-manager.test.d.ts +0 -2
  157. package/dist/common/analytics/package-manager.test.d.ts.map +0 -1
  158. package/dist/common/analytics/package-manager.test.js +0 -163
  159. package/dist/common/analytics/package-manager.test.js.map +0 -1
  160. package/dist/common/cli-dispatcher.test.d.ts +0 -2
  161. package/dist/common/cli-dispatcher.test.d.ts.map +0 -1
  162. package/dist/common/cli-dispatcher.test.js +0 -80
  163. package/dist/common/cli-dispatcher.test.js.map +0 -1
  164. package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts +0 -2
  165. package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts.map +0 -1
  166. package/dist/common/middleware/check-pnpm-lifecycle.test.js +0 -125
  167. package/dist/common/middleware/check-pnpm-lifecycle.test.js.map +0 -1
  168. package/dist/common/middleware/get-environment-param.test.d.ts +0 -2
  169. package/dist/common/middleware/get-environment-param.test.d.ts.map +0 -1
  170. package/dist/common/middleware/get-environment-param.test.js +0 -57
  171. package/dist/common/middleware/get-environment-param.test.js.map +0 -1
  172. package/dist/common/read-linked-config.test.d.ts +0 -2
  173. package/dist/common/read-linked-config.test.d.ts.map +0 -1
  174. package/dist/common/read-linked-config.test.js +0 -363
  175. package/dist/common/read-linked-config.test.js.map +0 -1
  176. package/dist/common/terminal.test.d.ts +0 -2
  177. package/dist/common/terminal.test.d.ts.map +0 -1
  178. package/dist/common/terminal.test.js +0 -101
  179. package/dist/common/terminal.test.js.map +0 -1
  180. package/dist/common/utils/build-environment-prompt-choices.test.d.ts +0 -2
  181. package/dist/common/utils/build-environment-prompt-choices.test.d.ts.map +0 -1
  182. package/dist/common/utils/build-environment-prompt-choices.test.js +0 -97
  183. package/dist/common/utils/build-environment-prompt-choices.test.js.map +0 -1
  184. package/dist/common/utils/format-environment-type.test.d.ts +0 -2
  185. package/dist/common/utils/format-environment-type.test.d.ts.map +0 -1
  186. package/dist/common/utils/format-environment-type.test.js +0 -32
  187. package/dist/common/utils/format-environment-type.test.js.map +0 -1
  188. package/dist/common/utils/pnpm-lifecycle.test.d.ts +0 -2
  189. package/dist/common/utils/pnpm-lifecycle.test.d.ts.map +0 -1
  190. package/dist/common/utils/pnpm-lifecycle.test.js +0 -196
  191. package/dist/common/utils/pnpm-lifecycle.test.js.map +0 -1
  192. package/dist/common/utils/pretty-print-environment-prompt.test.d.ts +0 -2
  193. package/dist/common/utils/pretty-print-environment-prompt.test.d.ts.map +0 -1
  194. package/dist/common/utils/pretty-print-environment-prompt.test.js +0 -42
  195. package/dist/common/utils/pretty-print-environment-prompt.test.js.map +0 -1
  196. package/dist/common/utils/sort-environments-for-prompt.test.d.ts +0 -2
  197. package/dist/common/utils/sort-environments-for-prompt.test.d.ts.map +0 -1
  198. package/dist/common/utils/sort-environments-for-prompt.test.js +0 -82
  199. package/dist/common/utils/sort-environments-for-prompt.test.js.map +0 -1
  200. package/dist/common/utils/stringify-config.test.d.ts +0 -2
  201. package/dist/common/utils/stringify-config.test.d.ts.map +0 -1
  202. package/dist/common/utils/stringify-config.test.js +0 -80
  203. package/dist/common/utils/stringify-config.test.js.map +0 -1
  204. package/dist/common/validators/argument-validators.spec.d.ts +0 -2
  205. package/dist/common/validators/argument-validators.spec.d.ts.map +0 -1
  206. package/dist/common/validators/argument-validators.spec.js +0 -181
  207. package/dist/common/validators/argument-validators.spec.js.map +0 -1
  208. package/dist/deploy/archive.local-registry.test.d.ts +0 -2
  209. package/dist/deploy/archive.local-registry.test.d.ts.map +0 -1
  210. package/dist/deploy/archive.local-registry.test.js +0 -100
  211. package/dist/deploy/archive.local-registry.test.js.map +0 -1
  212. package/dist/deploy/archive.test.d.ts +0 -2
  213. package/dist/deploy/archive.test.d.ts.map +0 -1
  214. package/dist/deploy/archive.test.js +0 -248
  215. package/dist/deploy/archive.test.js.map +0 -1
  216. package/dist/deploy/classify-build-probe.test.d.ts +0 -2
  217. package/dist/deploy/classify-build-probe.test.d.ts.map +0 -1
  218. package/dist/deploy/classify-build-probe.test.js +0 -51
  219. package/dist/deploy/classify-build-probe.test.js.map +0 -1
  220. package/dist/deploy/poll-deployment.test.d.ts +0 -2
  221. package/dist/deploy/poll-deployment.test.d.ts.map +0 -1
  222. package/dist/deploy/poll-deployment.test.js +0 -158
  223. package/dist/deploy/poll-deployment.test.js.map +0 -1
  224. package/dist/dev/zuplo-local-gitignore.test.d.ts +0 -2
  225. package/dist/dev/zuplo-local-gitignore.test.d.ts.map +0 -1
  226. package/dist/dev/zuplo-local-gitignore.test.js +0 -58
  227. package/dist/dev/zuplo-local-gitignore.test.js.map +0 -1
  228. package/dist/editor/e2e/editor.spec.d.ts +0 -2
  229. package/dist/editor/e2e/editor.spec.d.ts.map +0 -1
  230. package/dist/editor/e2e/editor.spec.js +0 -44
  231. package/dist/editor/e2e/editor.spec.js.map +0 -1
  232. package/dist/link/project-type.test.d.ts +0 -2
  233. package/dist/link/project-type.test.d.ts.map +0 -1
  234. package/dist/link/project-type.test.js +0 -225
  235. package/dist/link/project-type.test.js.map +0 -1
  236. package/dist/lint/resolve-binary.test.d.ts +0 -2
  237. package/dist/lint/resolve-binary.test.d.ts.map +0 -1
  238. package/dist/lint/resolve-binary.test.js +0 -155
  239. package/dist/lint/resolve-binary.test.js.map +0 -1
  240. package/dist/open-api/convert/handler.spec.d.ts +0 -2
  241. package/dist/open-api/convert/handler.spec.d.ts.map +0 -1
  242. package/dist/open-api/convert/handler.spec.js +0 -301
  243. package/dist/open-api/convert/handler.spec.js.map +0 -1
  244. package/dist/open-api/merge/handler.spec.d.ts +0 -2
  245. package/dist/open-api/merge/handler.spec.d.ts.map +0 -1
  246. package/dist/open-api/merge/handler.spec.js +0 -673
  247. package/dist/open-api/merge/handler.spec.js.map +0 -1
  248. package/dist/open-api/overlay/handler.spec.d.ts +0 -2
  249. package/dist/open-api/overlay/handler.spec.d.ts.map +0 -1
  250. package/dist/open-api/overlay/handler.spec.js +0 -346
  251. package/dist/open-api/overlay/handler.spec.js.map +0 -1
  252. package/dist/source/ai-gateway/files.test.d.ts +0 -2
  253. package/dist/source/ai-gateway/files.test.d.ts.map +0 -1
  254. package/dist/source/ai-gateway/files.test.js +0 -135
  255. package/dist/source/ai-gateway/files.test.js.map +0 -1
  256. package/dist/source/ai-gateway/handler.test.d.ts +0 -2
  257. package/dist/source/ai-gateway/handler.test.d.ts.map +0 -1
  258. package/dist/source/ai-gateway/handler.test.js +0 -113
  259. package/dist/source/ai-gateway/handler.test.js.map +0 -1
  260. package/dist/source/ai-gateway/package.test.d.ts +0 -2
  261. package/dist/source/ai-gateway/package.test.d.ts.map +0 -1
  262. package/dist/source/ai-gateway/package.test.js +0 -30
  263. package/dist/source/ai-gateway/package.test.js.map +0 -1
  264. package/dist/source/ai-gateway/planner.test.d.ts +0 -2
  265. package/dist/source/ai-gateway/planner.test.d.ts.map +0 -1
  266. package/dist/source/ai-gateway/planner.test.js +0 -330
  267. package/dist/source/ai-gateway/planner.test.js.map +0 -1
  268. package/dist/source/ai-gateway/release.test.d.ts +0 -2
  269. package/dist/source/ai-gateway/release.test.d.ts.map +0 -1
  270. package/dist/source/ai-gateway/release.test.js +0 -62
  271. package/dist/source/ai-gateway/release.test.js.map +0 -1
  272. package/dist/test/invoke-test.test.d.ts +0 -2
  273. package/dist/test/invoke-test.test.d.ts.map +0 -1
  274. package/dist/test/invoke-test.test.js +0 -150
  275. package/dist/test/invoke-test.test.js.map +0 -1
  276. package/dist/test/test-files.test.d.ts +0 -2
  277. package/dist/test/test-files.test.d.ts.map +0 -1
  278. package/dist/test/test-files.test.js +0 -57
  279. package/dist/test/test-files.test.js.map +0 -1
  280. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts +0 -2
  281. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts.map +0 -1
  282. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js +0 -289
  283. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js.map +0 -1
  284. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts +0 -2
  285. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts.map +0 -1
  286. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js +0 -181
  287. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js.map +0 -1
  288. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts +0 -2
  289. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts.map +0 -1
  290. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js +0 -399
  291. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js.map +0 -1
  292. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts +0 -2
  293. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts.map +0 -1
  294. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js +0 -779
  295. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js.map +0 -1
  296. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts +0 -2
  297. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts.map +0 -1
  298. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js +0 -269
  299. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js.map +0 -1
  300. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts +0 -2
  301. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts.map +0 -1
  302. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js +0 -93
  303. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js.map +0 -1
  304. package/node_modules/@zuplo/runtime/out/esm/chunk-6YPRGG62.js.map +0 -1
  305. package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js +0 -37
  306. package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js.map +0 -1
  307. /package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js.map → chunk-CDEAY3VY.js.map} +0 -0
  308. /package/node_modules/@zuplo/runtime/out/esm/{chunk-PBDT4FDO.js.LEGAL.txt → chunk-LVSZ3WTO.js.LEGAL.txt} +0 -0
  309. /package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js.map → chunk-NUVXDVLJ.js.map} +0 -0
  310. /package/node_modules/@zuplo/runtime/out/esm/{chunk-6YPRGG62.js.LEGAL.txt → chunk-RHU3Z7DA.js.LEGAL.txt} +0 -0
@@ -1,395 +0,0 @@
1
- import nock from "nock";
2
- import yargs from "yargs/yargs";
3
- import linkCommand from "../../cmds/link.js";
4
- import { confirmLinkedValue, readLinkedConfig, } from "../../common/read-linked-config.js";
5
- import { isInteractiveTerminal } from "../../common/terminal.js";
6
- import { syncProjectTypeForLink } from "../../link/project-type.js";
7
- import { cleanupTest, RequestCapture, setupAuthenticatedNock, setupTestEnvironment, TEST_ACCOUNT_NAME, TEST_API_BASE, TEST_AUTH_TOKEN, TEST_PROJECT_NAME, } from "./test-utils.js";
8
- jest.mock("../../common/terminal.js", () => ({
9
- __esModule: true,
10
- isInteractiveTerminal: jest.fn().mockReturnValue(true),
11
- }));
12
- jest.mock("../../common/read-linked-config.js", () => ({
13
- __esModule: true,
14
- confirmLinkedValue: jest.fn().mockResolvedValue(true),
15
- readLinkedConfig: jest.fn().mockResolvedValue({}),
16
- USE_LINKED_DETAILS: "useLinkedDetails",
17
- ignoreLinkedDetails: jest
18
- .fn()
19
- .mockImplementation((argv) => {
20
- argv["useLinkedDetails"] = false;
21
- }),
22
- }));
23
- jest.mock("../../common/validators/file-system-validator.js", () => ({
24
- ZuploProjectValidator: jest.fn().mockImplementation(() => ({
25
- validate: jest.fn().mockResolvedValue(true),
26
- })),
27
- }));
28
- jest.mock("../../common/populate.js", () => ({
29
- pullSystemConfig: jest.fn().mockResolvedValue(undefined),
30
- pullLocalConfig: jest.fn().mockResolvedValue(undefined),
31
- safeMergeConfig: jest.fn().mockResolvedValue(undefined),
32
- }));
33
- jest.mock("../../link/project-type.js", () => ({
34
- __esModule: true,
35
- syncProjectTypeForLink: jest.fn().mockResolvedValue(undefined),
36
- }));
37
- async function executeLinkCommand(args) {
38
- const yargsInstance = yargs([])
39
- .command(linkCommand)
40
- .help(false)
41
- .version(false)
42
- .exitProcess(false);
43
- const commandArgs = ["link"];
44
- if (args.account) {
45
- commandArgs.push("--account", args.account);
46
- }
47
- if (args.project) {
48
- commandArgs.push("--project", args.project);
49
- }
50
- if (args["api-key"]) {
51
- commandArgs.push("--api-key", args["api-key"]);
52
- }
53
- if (args.environment) {
54
- commandArgs.push("--environment", args.environment);
55
- }
56
- if (args.dir) {
57
- commandArgs.push("--dir", args.dir);
58
- }
59
- return await yargsInstance.parse(commandArgs);
60
- }
61
- const mockPrintResult = jest.mocked(require("../../common/output.js").printResultToConsoleAndExitGracefully);
62
- const mockPrintCriticalFailure = jest.mocked(require("../../common/output.js").printCriticalFailureToConsoleAndExit);
63
- describe("Link Command Integration Tests", () => {
64
- let requestCapture;
65
- beforeEach(() => {
66
- setupTestEnvironment();
67
- requestCapture = new RequestCapture();
68
- nock.disableNetConnect();
69
- jest.clearAllMocks();
70
- jest.mocked(isInteractiveTerminal).mockReturnValue(true);
71
- });
72
- afterEach(() => {
73
- cleanupTest();
74
- requestCapture.clear();
75
- });
76
- describe("Link with project and environment specified", () => {
77
- it("should sync project type when project and environment are provided", async () => {
78
- await executeLinkCommand({
79
- account: TEST_ACCOUNT_NAME,
80
- project: TEST_PROJECT_NAME,
81
- "api-key": TEST_AUTH_TOKEN,
82
- environment: "development",
83
- dir: ".",
84
- });
85
- expect(mockPrintResult).toHaveBeenCalledWith(expect.stringContaining(`Successfully linked your local directory to the ${TEST_PROJECT_NAME} project`));
86
- expect(syncProjectTypeForLink).toHaveBeenCalledWith({
87
- sourceDirectory: ".",
88
- accountName: TEST_ACCOUNT_NAME,
89
- projectName: TEST_PROJECT_NAME,
90
- authToken: TEST_AUTH_TOKEN,
91
- });
92
- const capturedRequests = requestCapture.getRequests();
93
- expect(capturedRequests).toEqual([]);
94
- });
95
- });
96
- describe("Link with automatic project selection", () => {
97
- it("should intercept GET request to list projects", async () => {
98
- const mockProjectsResponse = {
99
- data: [
100
- {
101
- name: TEST_PROJECT_NAME,
102
- accountName: TEST_ACCOUNT_NAME,
103
- description: "Test project",
104
- createdAt: "2024-01-01T00:00:00Z",
105
- },
106
- ],
107
- };
108
- const mockEnvironmentsResponse = {
109
- data: [
110
- {
111
- name: "development",
112
- environmentType: "development",
113
- branchName: "main",
114
- accountName: TEST_ACCOUNT_NAME,
115
- projectName: TEST_PROJECT_NAME,
116
- },
117
- ],
118
- };
119
- const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
120
- .get("/v1/projects")
121
- .query({ accountName: TEST_ACCOUNT_NAME })
122
- .reply(200, mockProjectsResponse);
123
- const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
124
- .get("/v1/environments")
125
- .query({
126
- accountName: TEST_ACCOUNT_NAME,
127
- projectName: TEST_PROJECT_NAME,
128
- })
129
- .reply(200, mockEnvironmentsResponse);
130
- const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
131
- .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
132
- .reply(200, { data: [] });
133
- [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {
134
- scope.on("request", (req, interceptor, body) => {
135
- requestCapture.capture(req, interceptor, body);
136
- });
137
- });
138
- await executeLinkCommand({
139
- account: TEST_ACCOUNT_NAME,
140
- "api-key": TEST_AUTH_TOKEN,
141
- dir: ".",
142
- });
143
- expect(projectsScope.isDone()).toBe(true);
144
- expect(environmentsScope.isDone()).toBe(true);
145
- expect(deploymentsScope.isDone()).toBe(true);
146
- expect(mockPrintResult).toHaveBeenCalledWith(expect.stringContaining(`Successfully linked your local directory to the ${TEST_PROJECT_NAME} project`));
147
- const capturedRequests = requestCapture.getRequests();
148
- expect(capturedRequests).toMatchSnapshot("link-automatic-selection-requests");
149
- });
150
- it("should handle multiple projects and prompt selection", async () => {
151
- const mockProjectsResponse = {
152
- data: [
153
- { name: "project-1", accountName: TEST_ACCOUNT_NAME },
154
- { name: "project-2", accountName: TEST_ACCOUNT_NAME },
155
- ],
156
- };
157
- const mockEnvironmentsResponse = {
158
- data: [
159
- {
160
- name: "development",
161
- environmentType: "development",
162
- branchName: "main",
163
- accountName: TEST_ACCOUNT_NAME,
164
- projectName: "project-1",
165
- },
166
- ],
167
- };
168
- const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
169
- .get("/v1/projects")
170
- .query({ accountName: TEST_ACCOUNT_NAME })
171
- .reply(200, mockProjectsResponse);
172
- const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
173
- .get("/v1/environments")
174
- .query({
175
- accountName: TEST_ACCOUNT_NAME,
176
- projectName: "project-1",
177
- })
178
- .reply(200, mockEnvironmentsResponse);
179
- const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
180
- .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/project-1/deployments`)
181
- .reply(200, { data: [] });
182
- [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {
183
- scope.on("request", (req, interceptor, body) => {
184
- requestCapture.capture(req, interceptor, body);
185
- });
186
- });
187
- await executeLinkCommand({
188
- account: TEST_ACCOUNT_NAME,
189
- "api-key": TEST_AUTH_TOKEN,
190
- dir: ".",
191
- });
192
- expect(projectsScope.isDone()).toBe(true);
193
- expect(environmentsScope.isDone()).toBe(true);
194
- expect(deploymentsScope.isDone()).toBe(true);
195
- const capturedRequests = requestCapture.getRequests();
196
- expect(capturedRequests).toMatchSnapshot("link-multiple-projects-requests");
197
- });
198
- });
199
- describe("Link error handling", () => {
200
- it("should fail when no environments exist", async () => {
201
- const mockProjectsResponse = {
202
- data: [{ name: TEST_PROJECT_NAME, accountName: TEST_ACCOUNT_NAME }],
203
- };
204
- const mockEmptyEnvironmentsResponse = { data: [] };
205
- const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
206
- .get("/v1/projects")
207
- .query({ accountName: TEST_ACCOUNT_NAME })
208
- .reply(200, mockProjectsResponse);
209
- const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
210
- .get("/v1/environments")
211
- .query({
212
- accountName: TEST_ACCOUNT_NAME,
213
- projectName: TEST_PROJECT_NAME,
214
- })
215
- .reply(200, mockEmptyEnvironmentsResponse);
216
- const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
217
- .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
218
- .reply(200, { data: [] });
219
- [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {
220
- scope.on("request", (req, interceptor, body) => {
221
- requestCapture.capture(req, interceptor, body);
222
- });
223
- });
224
- await expect(executeLinkCommand({
225
- account: TEST_ACCOUNT_NAME,
226
- "api-key": TEST_AUTH_TOKEN,
227
- dir: ".",
228
- })).rejects.toThrow("Process would exit");
229
- expect(projectsScope.isDone()).toBe(true);
230
- expect(environmentsScope.isDone()).toBe(true);
231
- expect(deploymentsScope.isDone()).toBe(true);
232
- const capturedRequests = requestCapture.getRequests();
233
- expect(capturedRequests.length).toBeGreaterThan(0);
234
- expect(mockPrintCriticalFailure).toHaveBeenCalledWith(expect.stringContaining("any environments"));
235
- });
236
- });
237
- describe("Error handling", () => {
238
- it("should handle projects list failure", async () => {
239
- const errorResponse = {
240
- error: "Unauthorized",
241
- message: "Invalid API key",
242
- statusCode: 401,
243
- };
244
- const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
245
- .get("/v1/projects")
246
- .query({ accountName: TEST_ACCOUNT_NAME })
247
- .reply(401, errorResponse);
248
- scope.on("request", (req, interceptor, body) => {
249
- requestCapture.capture(req, interceptor, body);
250
- });
251
- await expect(executeLinkCommand({
252
- account: TEST_ACCOUNT_NAME,
253
- "api-key": TEST_AUTH_TOKEN,
254
- dir: ".",
255
- })).rejects.toThrow("Process would exit");
256
- expect(scope.isDone()).toBe(true);
257
- expect(mockPrintCriticalFailure).toHaveBeenCalled();
258
- const capturedRequests = requestCapture.getRequests();
259
- expect(capturedRequests).toMatchSnapshot("link-projects-error-requests");
260
- });
261
- it("should handle environments list failure", async () => {
262
- const mockProjectsResponse = {
263
- data: [{ name: TEST_PROJECT_NAME, accountName: TEST_ACCOUNT_NAME }],
264
- };
265
- const errorResponse = {
266
- error: "Forbidden",
267
- message: "Access denied to project",
268
- statusCode: 403,
269
- };
270
- const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
271
- .get("/v1/projects")
272
- .query({ accountName: TEST_ACCOUNT_NAME })
273
- .reply(200, mockProjectsResponse);
274
- const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
275
- .get("/v1/environments")
276
- .query({
277
- accountName: TEST_ACCOUNT_NAME,
278
- projectName: TEST_PROJECT_NAME,
279
- })
280
- .reply(403, errorResponse);
281
- [projectsScope, environmentsScope].forEach((scope) => {
282
- scope.on("request", (req, interceptor, body) => {
283
- requestCapture.capture(req, interceptor, body);
284
- });
285
- });
286
- await expect(executeLinkCommand({
287
- account: TEST_ACCOUNT_NAME,
288
- "api-key": TEST_AUTH_TOKEN,
289
- dir: ".",
290
- })).rejects.toThrow("Process would exit");
291
- expect(projectsScope.isDone()).toBe(true);
292
- expect(environmentsScope.isDone()).toBe(true);
293
- expect(mockPrintCriticalFailure).toHaveBeenCalled();
294
- const capturedRequests = requestCapture.getRequests();
295
- expect(capturedRequests).toMatchSnapshot("link-environments-error-requests");
296
- });
297
- });
298
- describe("Request validation", () => {
299
- it("should include correct headers for API requests", async () => {
300
- const mockProjectsResponse = {
301
- data: [{ name: TEST_PROJECT_NAME, accountName: TEST_ACCOUNT_NAME }],
302
- };
303
- const mockEnvironmentsResponse = {
304
- data: [
305
- {
306
- name: "development",
307
- environmentType: "development",
308
- branchName: "main",
309
- accountName: TEST_ACCOUNT_NAME,
310
- projectName: TEST_PROJECT_NAME,
311
- },
312
- ],
313
- };
314
- const projectsScope = nock(TEST_API_BASE)
315
- .get("/v1/projects")
316
- .query({ accountName: TEST_ACCOUNT_NAME })
317
- .matchHeader("authorization", `Bearer ${TEST_AUTH_TOKEN}`)
318
- .reply(200, mockProjectsResponse);
319
- const environmentsScope = nock(TEST_API_BASE)
320
- .get("/v1/environments")
321
- .query({
322
- accountName: TEST_ACCOUNT_NAME,
323
- projectName: TEST_PROJECT_NAME,
324
- })
325
- .matchHeader("authorization", `Bearer ${TEST_AUTH_TOKEN}`)
326
- .reply(200, mockEnvironmentsResponse);
327
- const deploymentsScope = nock(TEST_API_BASE)
328
- .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
329
- .matchHeader("authorization", `Bearer ${TEST_AUTH_TOKEN}`)
330
- .reply(200, { data: [] });
331
- [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {
332
- scope.on("request", (req, interceptor, body) => {
333
- requestCapture.capture(req, interceptor, body);
334
- });
335
- });
336
- await executeLinkCommand({
337
- account: TEST_ACCOUNT_NAME,
338
- "api-key": TEST_AUTH_TOKEN,
339
- dir: ".",
340
- });
341
- expect(projectsScope.isDone()).toBe(true);
342
- expect(environmentsScope.isDone()).toBe(true);
343
- expect(deploymentsScope.isDone()).toBe(true);
344
- const capturedRequests = requestCapture.getRequests();
345
- expect(capturedRequests).toMatchSnapshot("link-headers-validation");
346
- });
347
- });
348
- describe("Link always re-prompts from scratch", () => {
349
- it("should not offer linked account/project/environment even when .env.zuplo is present", async () => {
350
- jest.mocked(readLinkedConfig).mockResolvedValue({
351
- accountName: TEST_ACCOUNT_NAME,
352
- projectName: TEST_PROJECT_NAME,
353
- });
354
- jest
355
- .mocked(confirmLinkedValue)
356
- .mockRejectedValue(new Error("link should never call confirmLinkedValue"));
357
- const accountsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
358
- .get("/v1/accounts")
359
- .reply(200, {
360
- data: [{ name: TEST_ACCOUNT_NAME }],
361
- });
362
- const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
363
- .get("/v1/projects")
364
- .query({ accountName: TEST_ACCOUNT_NAME })
365
- .reply(200, { data: [{ name: TEST_PROJECT_NAME }] });
366
- const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
367
- .get("/v1/environments")
368
- .query({
369
- accountName: TEST_ACCOUNT_NAME,
370
- projectName: TEST_PROJECT_NAME,
371
- })
372
- .reply(200, {
373
- data: [
374
- {
375
- name: "development",
376
- environmentType: "development",
377
- branchName: "main",
378
- accountName: TEST_ACCOUNT_NAME,
379
- projectName: TEST_PROJECT_NAME,
380
- },
381
- ],
382
- });
383
- const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))
384
- .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`)
385
- .reply(200, { data: [] });
386
- await executeLinkCommand({ dir: "." });
387
- expect(accountsScope.isDone()).toBe(true);
388
- expect(projectsScope.isDone()).toBe(true);
389
- expect(environmentsScope.isDone()).toBe(true);
390
- expect(deploymentsScope.isDone()).toBe(true);
391
- expect(confirmLinkedValue).not.toHaveBeenCalled();
392
- });
393
- });
394
- });
395
- //# sourceMappingURL=link.integration.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"link.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/link.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the link command\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport linkCommand from \"../../cmds/link.js\";\nimport {\n confirmLinkedValue,\n readLinkedConfig,\n} from \"../../common/read-linked-config.js\";\nimport { isInteractiveTerminal } from \"../../common/terminal.js\";\nimport { syncProjectTypeForLink } from \"../../link/project-type.js\";\nimport {\n cleanupTest,\n RequestCapture,\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\n// Tests exercise interactive selection flows — treat the terminal as interactive by default.\njest.mock(\"../../common/terminal.js\", () => ({\n __esModule: true,\n isInteractiveTerminal: jest.fn().mockReturnValue(true),\n}));\n\n// Mock read-linked-config so tests can control linked state without touching the filesystem.\n// Default: no linked values and confirmLinkedValue always confirms — overridden per-test as needed.\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\n// Mock file system validator\njest.mock(\"../../common/validators/file-system-validator.js\", () => ({\n ZuploProjectValidator: jest.fn().mockImplementation(() => ({\n validate: jest.fn().mockResolvedValue(true),\n })),\n}));\n\n// Mock link population functions to prevent file system operations\njest.mock(\"../../common/populate.js\", () => ({\n pullSystemConfig: jest.fn().mockResolvedValue(undefined),\n pullLocalConfig: jest.fn().mockResolvedValue(undefined),\n safeMergeConfig: jest.fn().mockResolvedValue(undefined),\n}));\n\njest.mock(\"../../link/project-type.js\", () => ({\n __esModule: true,\n syncProjectTypeForLink: jest.fn().mockResolvedValue(undefined),\n}));\n\n/**\n * Execute link command with given arguments using actual yargs command\n */\nasync function executeLinkCommand(args: {\n account?: string;\n project?: string;\n \"api-key\"?: string;\n environment?: string;\n dir?: string;\n}) {\n const yargsInstance = yargs([])\n .command(linkCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"link\"];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args.project) {\n commandArgs.push(\"--project\", args.project);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n if (args.environment) {\n commandArgs.push(\"--environment\", args.environment);\n }\n\n if (args.dir) {\n commandArgs.push(\"--dir\", args.dir);\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n// Get the mocked functions\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintCriticalFailure = jest.mocked(\n require(\"../../common/output.js\").printCriticalFailureToConsoleAndExit\n);\n\ndescribe(\"Link Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n requestCapture = new RequestCapture();\n\n // Disable real HTTP requests\n nock.disableNetConnect();\n\n // Clear mock calls from previous tests\n jest.clearAllMocks();\n jest.mocked(isInteractiveTerminal).mockReturnValue(true);\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n describe(\"Link with project and environment specified\", () => {\n it(\"should sync project type when project and environment are provided\", async () => {\n await executeLinkCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n environment: \"development\",\n dir: \".\",\n });\n\n // Verify successful linking message\n expect(mockPrintResult).toHaveBeenCalledWith(\n expect.stringContaining(\n `Successfully linked your local directory to the ${TEST_PROJECT_NAME} project`\n )\n );\n\n expect(syncProjectTypeForLink).toHaveBeenCalledWith({\n sourceDirectory: \".\",\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // No selection API requests are needed when all params are provided.\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toEqual([]);\n });\n });\n\n describe(\"Link with automatic project selection\", () => {\n it(\"should intercept GET request to list projects\", async () => {\n const mockProjectsResponse = {\n data: [\n {\n name: TEST_PROJECT_NAME,\n accountName: TEST_ACCOUNT_NAME,\n description: \"Test project\",\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n };\n\n const mockEnvironmentsResponse = {\n data: [\n {\n name: \"development\",\n environmentType: \"development\",\n branchName: \"main\",\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n },\n ],\n };\n\n // Mock the middleware call to /v1/projects?accountName=... (fetchProject middleware)\n const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/projects\")\n .query({ accountName: TEST_ACCOUNT_NAME })\n .reply(200, mockProjectsResponse);\n\n // Mock the link handler call to /v1/environments\n const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/environments\")\n .query({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n })\n .reply(200, mockEnvironmentsResponse);\n\n // Mock the deployments endpoint (used to surface working-copy deployments)\n const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(200, { data: [] });\n\n [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n });\n\n await executeLinkCommand({\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n dir: \".\",\n });\n\n expect(projectsScope.isDone()).toBe(true);\n expect(environmentsScope.isDone()).toBe(true);\n expect(deploymentsScope.isDone()).toBe(true);\n\n expect(mockPrintResult).toHaveBeenCalledWith(\n expect.stringContaining(\n `Successfully linked your local directory to the ${TEST_PROJECT_NAME} project`\n )\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"link-automatic-selection-requests\"\n );\n });\n\n it(\"should handle multiple projects and prompt selection\", async () => {\n const mockProjectsResponse = {\n data: [\n { name: \"project-1\", accountName: TEST_ACCOUNT_NAME },\n { name: \"project-2\", accountName: TEST_ACCOUNT_NAME },\n ],\n };\n\n const mockEnvironmentsResponse = {\n data: [\n {\n name: \"development\",\n environmentType: \"development\",\n branchName: \"main\",\n accountName: TEST_ACCOUNT_NAME,\n projectName: \"project-1\", // inquirer mock will select first project\n },\n ],\n };\n\n // Mock the middleware call to /v1/projects?accountName=... (fetchProject middleware)\n const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/projects\")\n .query({ accountName: TEST_ACCOUNT_NAME })\n .reply(200, mockProjectsResponse);\n\n // Mock the link handler call to /v1/environments (will use first project from inquirer mock)\n const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/environments\")\n .query({\n accountName: TEST_ACCOUNT_NAME,\n projectName: \"project-1\",\n })\n .reply(200, mockEnvironmentsResponse);\n\n // Mock the deployments endpoint (used to surface working-copy deployments)\n const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/projects/project-1/deployments`)\n .reply(200, { data: [] });\n\n [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n });\n\n await executeLinkCommand({\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n dir: \".\",\n });\n\n expect(projectsScope.isDone()).toBe(true);\n expect(environmentsScope.isDone()).toBe(true);\n expect(deploymentsScope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"link-multiple-projects-requests\"\n );\n });\n });\n\n describe(\"Link error handling\", () => {\n it(\"should fail when no environments exist\", async () => {\n const mockProjectsResponse = {\n data: [{ name: TEST_PROJECT_NAME, accountName: TEST_ACCOUNT_NAME }],\n };\n\n const mockEmptyEnvironmentsResponse = { data: [] };\n\n // Mock the middleware call to /v1/projects?accountName=... (fetchProject middleware)\n const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/projects\")\n .query({ accountName: TEST_ACCOUNT_NAME })\n .reply(200, mockProjectsResponse);\n\n // Mock the environments call (returns empty)\n const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/environments\")\n .query({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n })\n .reply(200, mockEmptyEnvironmentsResponse);\n\n // Mock the deployments endpoint (also returns empty - no working copies either)\n const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(200, { data: [] });\n\n [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n });\n\n // Should throw because there are no environments to link against\n await expect(\n executeLinkCommand({\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n dir: \".\",\n })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(projectsScope.isDone()).toBe(true);\n expect(environmentsScope.isDone()).toBe(true);\n expect(deploymentsScope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests.length).toBeGreaterThan(0);\n\n // Verify the critical failure was called with the right message\n expect(mockPrintCriticalFailure).toHaveBeenCalledWith(\n expect.stringContaining(\"any environments\")\n );\n });\n });\n\n describe(\"Error handling\", () => {\n it(\"should handle projects list failure\", async () => {\n const errorResponse = {\n error: \"Unauthorized\",\n message: \"Invalid API key\",\n statusCode: 401,\n };\n\n // Mock the middleware call to /v1/projects?accountName=... (fetchProject middleware)\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/projects\")\n .query({ accountName: TEST_ACCOUNT_NAME })\n .reply(401, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n // Expect the function to throw (simulating process exit)\n await expect(\n executeLinkCommand({\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n dir: \".\",\n })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintCriticalFailure).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"link-projects-error-requests\");\n });\n\n it(\"should handle environments list failure\", async () => {\n const mockProjectsResponse = {\n data: [{ name: TEST_PROJECT_NAME, accountName: TEST_ACCOUNT_NAME }],\n };\n\n const errorResponse = {\n error: \"Forbidden\",\n message: \"Access denied to project\",\n statusCode: 403,\n };\n\n // Mock the middleware call to /v1/projects?accountName=... (fetchProject middleware)\n const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/projects\")\n .query({ accountName: TEST_ACCOUNT_NAME })\n .reply(200, mockProjectsResponse);\n\n // Mock the link handler call to /v1/environments (will fail)\n const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/environments\")\n .query({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n })\n .reply(403, errorResponse);\n\n [projectsScope, environmentsScope].forEach((scope) => {\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n });\n\n // Expect the function to throw (simulating process exit)\n await expect(\n executeLinkCommand({\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n dir: \".\",\n })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(projectsScope.isDone()).toBe(true);\n expect(environmentsScope.isDone()).toBe(true);\n expect(mockPrintCriticalFailure).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"link-environments-error-requests\"\n );\n });\n });\n\n describe(\"Request validation\", () => {\n it(\"should include correct headers for API requests\", async () => {\n const mockProjectsResponse = {\n data: [{ name: TEST_PROJECT_NAME, accountName: TEST_ACCOUNT_NAME }],\n };\n\n const mockEnvironmentsResponse = {\n data: [\n {\n name: \"development\",\n environmentType: \"development\",\n branchName: \"main\",\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n },\n ],\n };\n\n // Mock the middleware call to /v1/projects?accountName=... (fetchProject middleware)\n const projectsScope = nock(TEST_API_BASE)\n .get(\"/v1/projects\")\n .query({ accountName: TEST_ACCOUNT_NAME })\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, mockProjectsResponse);\n\n // Mock the link handler call to /v1/environments\n const environmentsScope = nock(TEST_API_BASE)\n .get(\"/v1/environments\")\n .query({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n })\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, mockEnvironmentsResponse);\n\n // Mock the deployments endpoint (used to surface working-copy deployments)\n const deploymentsScope = nock(TEST_API_BASE)\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, { data: [] });\n\n [projectsScope, environmentsScope, deploymentsScope].forEach((scope) => {\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n });\n\n await executeLinkCommand({\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n dir: \".\",\n });\n\n expect(projectsScope.isDone()).toBe(true);\n expect(environmentsScope.isDone()).toBe(true);\n expect(deploymentsScope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"link-headers-validation\");\n });\n });\n\n describe(\"Link always re-prompts from scratch\", () => {\n it(\"should not offer linked account/project/environment even when .env.zuplo is present\", async () => {\n // Simulate an existing .env.zuplo with fully linked values\n jest.mocked(readLinkedConfig).mockResolvedValue({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n });\n // confirmLinkedValue should never be called — if it is, fail the test immediately\n jest\n .mocked(confirmLinkedValue)\n .mockRejectedValue(\n new Error(\"link should never call confirmLinkedValue\")\n );\n\n // The link command bypasses linked config, so it must go through the full\n // interactive selection flow: accounts → projects → environments.\n const accountsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/accounts\")\n .reply(200, {\n data: [{ name: TEST_ACCOUNT_NAME }],\n });\n\n const projectsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/projects\")\n .query({ accountName: TEST_ACCOUNT_NAME })\n .reply(200, { data: [{ name: TEST_PROJECT_NAME }] });\n\n const environmentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/environments\")\n .query({\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n })\n .reply(200, {\n data: [\n {\n name: \"development\",\n environmentType: \"development\",\n branchName: \"main\",\n accountName: TEST_ACCOUNT_NAME,\n projectName: TEST_PROJECT_NAME,\n },\n ],\n });\n\n const deploymentsScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(200, { data: [] });\n\n // Run link WITHOUT passing --account (so fetchAccount middleware runs)\n await executeLinkCommand({ dir: \".\" });\n\n // All selection endpoints must have been called — proving link went through\n // the full interactive flow rather than short-circuiting via linked config.\n expect(accountsScope.isDone()).toBe(true);\n expect(projectsScope.isDone()).toBe(true);\n expect(environmentsScope.isDone()).toBe(true);\n expect(deploymentsScope.isDone()).toBe(true);\n\n // confirmLinkedValue must never have been called\n expect(confirmLinkedValue).not.toHaveBeenCalled();\n });\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=linked-config-cascade.integration.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"linked-config-cascade.integration.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/linked-config-cascade.integration.test.ts"],"names":[],"mappings":""}
@@ -1,179 +0,0 @@
1
- import nock from "nock";
2
- import { confirmLinkedConfig } from "../../common/middleware/confirm-linked-config.js";
3
- import { fetchAccount } from "../../common/middleware/get-account-param.js";
4
- import { fetchEnvironment } from "../../common/middleware/get-environment-param.js";
5
- import { fetchProject } from "../../common/middleware/get-project-param.js";
6
- import { printCriticalFailureToConsoleAndExit } from "../../common/output.js";
7
- import { confirmLinkedValue, readLinkedConfig, USE_LINKED_DETAILS, } from "../../common/read-linked-config.js";
8
- import { isInteractiveTerminal } from "../../common/terminal.js";
9
- import { cleanupTest, setupAuthenticatedNock, setupTestEnvironment, TEST_ACCOUNT_NAME, TEST_API_BASE, TEST_AUTH_TOKEN, TEST_PROJECT_NAME, } from "./test-utils.js";
10
- jest.mock("../../common/read-linked-config.js", () => ({
11
- __esModule: true,
12
- confirmLinkedValue: jest.fn().mockResolvedValue(true),
13
- readLinkedConfig: jest.fn().mockResolvedValue({}),
14
- USE_LINKED_DETAILS: "useLinkedDetails",
15
- ignoreLinkedDetails: jest
16
- .fn()
17
- .mockImplementation((argv) => {
18
- argv["useLinkedDetails"] = false;
19
- }),
20
- }));
21
- jest.mock("../../common/terminal.js", () => ({
22
- __esModule: true,
23
- isInteractiveTerminal: jest.fn().mockReturnValue(true),
24
- }));
25
- describe("Linked-config cascade decline", () => {
26
- beforeEach(() => {
27
- setupTestEnvironment();
28
- nock.disableNetConnect();
29
- jest.clearAllMocks();
30
- jest.mocked(isInteractiveTerminal).mockReturnValue(true);
31
- });
32
- afterEach(() => {
33
- cleanupTest();
34
- });
35
- it("sets useLinkedDetails to false when user declines linked account", async () => {
36
- jest.mocked(readLinkedConfig).mockResolvedValue({
37
- accountName: TEST_ACCOUNT_NAME,
38
- });
39
- jest.mocked(confirmLinkedValue).mockResolvedValue(false);
40
- setupAuthenticatedNock(nock(TEST_API_BASE))
41
- .get("/v1/accounts")
42
- .reply(200, { data: [{ name: TEST_ACCOUNT_NAME }] });
43
- const argv = { authToken: TEST_AUTH_TOKEN };
44
- await fetchAccount(argv);
45
- expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
46
- expect(argv[USE_LINKED_DETAILS]).toBe(false);
47
- expect(argv.account).toBe(TEST_ACCOUNT_NAME);
48
- });
49
- it("skips linked project prompt when useLinkedDetails is false", async () => {
50
- jest.mocked(readLinkedConfig).mockResolvedValue({
51
- accountName: TEST_ACCOUNT_NAME,
52
- projectName: TEST_PROJECT_NAME,
53
- });
54
- jest
55
- .mocked(confirmLinkedValue)
56
- .mockRejectedValue(new Error("fetchProject must not call confirmLinkedValue after decline"));
57
- setupAuthenticatedNock(nock(TEST_API_BASE))
58
- .get("/v1/projects")
59
- .query({ accountName: TEST_ACCOUNT_NAME })
60
- .reply(200, { data: [{ name: TEST_PROJECT_NAME }] });
61
- const argv = {
62
- authToken: TEST_AUTH_TOKEN,
63
- account: TEST_ACCOUNT_NAME,
64
- [USE_LINKED_DETAILS]: false,
65
- };
66
- await fetchProject(argv);
67
- expect(confirmLinkedValue).not.toHaveBeenCalled();
68
- expect(argv.project).toBe(TEST_PROJECT_NAME);
69
- });
70
- it("full cascade: declining account prevents linked project prompt", async () => {
71
- jest.mocked(readLinkedConfig).mockResolvedValue({
72
- accountName: TEST_ACCOUNT_NAME,
73
- projectName: TEST_PROJECT_NAME,
74
- });
75
- jest.mocked(confirmLinkedValue).mockResolvedValueOnce(false);
76
- setupAuthenticatedNock(nock(TEST_API_BASE))
77
- .get("/v1/accounts")
78
- .reply(200, { data: [{ name: TEST_ACCOUNT_NAME }] });
79
- setupAuthenticatedNock(nock(TEST_API_BASE))
80
- .get("/v1/projects")
81
- .query({ accountName: TEST_ACCOUNT_NAME })
82
- .reply(200, { data: [{ name: TEST_PROJECT_NAME }] });
83
- const argv = { authToken: TEST_AUTH_TOKEN };
84
- await fetchAccount(argv);
85
- await fetchProject(argv);
86
- expect(confirmLinkedValue).toHaveBeenCalledTimes(1);
87
- expect(argv[USE_LINKED_DETAILS]).toBe(false);
88
- });
89
- it("uses linked account silently when terminal is non-interactive", async () => {
90
- jest.mocked(readLinkedConfig).mockResolvedValue({
91
- accountName: TEST_ACCOUNT_NAME,
92
- });
93
- jest.mocked(isInteractiveTerminal).mockReturnValue(false);
94
- const argv = { authToken: TEST_AUTH_TOKEN };
95
- await fetchAccount(argv);
96
- expect(confirmLinkedValue).not.toHaveBeenCalled();
97
- expect(argv.account).toBe(TEST_ACCOUNT_NAME);
98
- });
99
- it("uses linked project silently when terminal is non-interactive", async () => {
100
- jest.mocked(readLinkedConfig).mockResolvedValue({
101
- accountName: TEST_ACCOUNT_NAME,
102
- projectName: TEST_PROJECT_NAME,
103
- });
104
- jest.mocked(isInteractiveTerminal).mockReturnValue(false);
105
- const argv = {
106
- authToken: TEST_AUTH_TOKEN,
107
- account: TEST_ACCOUNT_NAME,
108
- };
109
- await fetchProject(argv);
110
- expect(confirmLinkedValue).not.toHaveBeenCalled();
111
- expect(argv.project).toBe(TEST_PROJECT_NAME);
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
- });
148
- it("fails loudly when --project is omitted in non-interactive environments without linked config", async () => {
149
- jest.mocked(readLinkedConfig).mockResolvedValue({});
150
- jest.mocked(isInteractiveTerminal).mockReturnValue(false);
151
- const argv = {
152
- authToken: TEST_AUTH_TOKEN,
153
- account: TEST_ACCOUNT_NAME,
154
- };
155
- await expect(fetchProject(argv)).rejects.toThrow("Process would exit");
156
- expect(printCriticalFailureToConsoleAndExit).toHaveBeenCalledWith(expect.stringContaining("--project is required"));
157
- expect(argv.project).toBeUndefined();
158
- });
159
- it("fails loudly when --account is omitted in non-interactive environments without linked config", async () => {
160
- jest.mocked(readLinkedConfig).mockResolvedValue({});
161
- jest.mocked(isInteractiveTerminal).mockReturnValue(false);
162
- const argv = { authToken: TEST_AUTH_TOKEN };
163
- await expect(fetchAccount(argv)).rejects.toThrow("Process would exit");
164
- expect(printCriticalFailureToConsoleAndExit).toHaveBeenCalledWith(expect.stringContaining("--account is required"));
165
- expect(argv.account).toBeUndefined();
166
- });
167
- it("fails loudly when --environment is omitted in non-interactive environments", async () => {
168
- jest.mocked(isInteractiveTerminal).mockReturnValue(false);
169
- const argv = {
170
- authToken: TEST_AUTH_TOKEN,
171
- account: TEST_ACCOUNT_NAME,
172
- project: TEST_PROJECT_NAME,
173
- };
174
- await expect(fetchEnvironment(argv)).rejects.toThrow("Process would exit");
175
- expect(printCriticalFailureToConsoleAndExit).toHaveBeenCalledWith(expect.stringContaining("--environment is required"));
176
- expect(argv.environment).toBeUndefined();
177
- });
178
- });
179
- //# sourceMappingURL=linked-config-cascade.integration.test.js.map