@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,330 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { describe, it } from "node:test";
3
- import { AI_OAS, catalog, POLICIES, PROVENANCE, planUpgrade, readJson, } from "./planner.js";
4
- const oldest = catalog.snapshots[1];
5
- const original = catalog.snapshots[2];
6
- const internalOnlyRename = catalog.snapshots[5];
7
- const loadBalancing = catalog.snapshots[6];
8
- const latest = catalog.snapshots.find((s) => s.revision === catalog.target);
9
- const LOAD_BALANCING = "ai-gateway-load-balancing-inbound";
10
- function releaseCatalog(revision) {
11
- const end = catalog.snapshots.findIndex((s) => s.revision === revision) + 1;
12
- const shipped = new Set(catalog.snapshots.slice(0, end).map((s) => s.revision));
13
- return structuredClone({
14
- ...catalog,
15
- target: revision,
16
- snapshots: catalog.snapshots.slice(0, end),
17
- steps: catalog.steps.filter((s) => shipped.has(s.target)),
18
- assessments: catalog.assessments.filter((a) => shipped.has(a.revision)),
19
- });
20
- }
21
- const files = () => ({ ...original.files });
22
- function change(file, mutate) {
23
- const input = files();
24
- const value = JSON.parse(input[file]);
25
- mutate(value);
26
- input[file] = JSON.stringify(value, null, 2);
27
- return input;
28
- }
29
- function blocked(input, expected) {
30
- const before = structuredClone(input);
31
- const result = planUpgrade(input, "1.0.0");
32
- assert.match(result.blockers.join("\n"), expected);
33
- assert.deepEqual(result.after, {});
34
- assert.deepEqual(input, before);
35
- }
36
- describe("conservative versioned gateway planner", () => {
37
- it("upgrades several historical snapshots without changing existing definitions", () => {
38
- for (const snapshot of catalog.snapshots.slice(0, 4)) {
39
- const result = planUpgrade(snapshot.files, "1.0.0");
40
- assert.deepEqual(result.blockers, []);
41
- assert.ok(result.additions.length);
42
- const before = JSON.parse(snapshot.files[AI_OAS]);
43
- const after = JSON.parse(result.after[AI_OAS] ?? snapshot.files[AI_OAS]);
44
- for (const [key, value] of Object.entries(before.paths))
45
- assert.deepEqual(after.paths[key], value);
46
- assert.deepEqual(Object.keys(after.paths), [
47
- "/u/:app_id/(.*)",
48
- "/a/:app_id/(.*)",
49
- "/:app_id/(.*)",
50
- ]);
51
- const oldPolicies = JSON.parse(snapshot.files[POLICIES]).policies;
52
- const newPolicies = JSON.parse(result.after[POLICIES] ?? snapshot.files[POLICIES]).policies;
53
- assert.deepEqual(newPolicies.slice(0, oldPolicies.length), oldPolicies);
54
- const again = planUpgrade({ ...snapshot.files, ...result.after }, "1.0.0");
55
- assert.deepEqual(again.blockers, []);
56
- assert.deepEqual(again.additions, []);
57
- assert.deepEqual(again.after, {});
58
- }
59
- });
60
- it("preserves the original loader defaults and rejects customized historical loaders", () => {
61
- const historical = catalog.snapshots[0];
62
- const input = { ...historical.files };
63
- const result = planUpgrade(input, "1.0.0");
64
- assert.deepEqual(result.blockers, []);
65
- const loader = (raw) => JSON.parse(raw).policies.find((p) => p.name === "ai-gateway-configuration-loader-v2-inbound");
66
- assert.deepEqual(loader(result.after[POLICIES]).handler.options, {});
67
- assert.deepEqual(loader(result.after[POLICIES]), loader(input[POLICIES]));
68
- const policies = JSON.parse(input[POLICIES]);
69
- policies.policies.find((p) => p.name === "ai-gateway-configuration-loader-v2-inbound").handler.options.cacheTtlSeconds = 45;
70
- input[POLICIES] = JSON.stringify(policies);
71
- blocked(input, /required policy.*customized/);
72
- });
73
- it("preserves the previous template after the Internal Only rename", () => {
74
- const previous = catalog.snapshots[4];
75
- const result = planUpgrade(previous.files, "1.0.0", releaseCatalog(internalOnlyRename.revision));
76
- assert.deepEqual(result.blockers, []);
77
- assert.deepEqual(result.additions, []);
78
- assert.deepEqual(result.after, {});
79
- const historical = planUpgrade(files(), "1.0.0");
80
- assert.deepEqual(historical.blockers, []);
81
- assert.ok(!historical.additions.some((a) => a.key === "internal-only-inbound"));
82
- });
83
- it("adds only the Model Load Balancing declaration after the Internal Only rename", () => {
84
- const release = releaseCatalog(loadBalancing.revision);
85
- const declaration = JSON.parse(loadBalancing.files[POLICIES]).policies.find((p) => p.name === LOAD_BALANCING);
86
- for (const previous of [catalog.snapshots[4], internalOnlyRename]) {
87
- const result = planUpgrade(previous.files, "1.0.0", release);
88
- assert.deepEqual(result.blockers, []);
89
- assert.deepEqual(result.additions.map((a) => a.key), [LOAD_BALANCING]);
90
- assert.equal(result.after[AI_OAS], undefined);
91
- const before = JSON.parse(previous.files[POLICIES]).policies;
92
- const after = JSON.parse(result.after[POLICIES]).policies;
93
- assert.deepEqual(after.slice(0, -1), before);
94
- assert.deepEqual(after.at(-1), declaration);
95
- const again = planUpgrade({ ...previous.files, ...result.after }, "1.0.0", release);
96
- assert.deepEqual(again.blockers, []);
97
- assert.deepEqual(again.additions, []);
98
- assert.deepEqual(again.after, {});
99
- }
100
- });
101
- it("upgrades a project that the Internal Only release already upgraded", () => {
102
- const first = planUpgrade(original.files, "1.0.0", releaseCatalog(internalOnlyRename.revision));
103
- assert.deepEqual(first.blockers, []);
104
- const next = planUpgrade({ ...original.files, ...first.after }, "2.0.0", releaseCatalog(loadBalancing.revision));
105
- assert.deepEqual(next.blockers, []);
106
- assert.deepEqual(next.additions.map((a) => a.key), [LOAD_BALANCING]);
107
- assert.ok(JSON.parse(next.after[PROVENANCE]).appliedSteps.includes(`${loadBalancing.revision}:policy:${LOAD_BALANCING}`));
108
- });
109
- it("does not restore a deliberately removed Model Load Balancing declaration", () => {
110
- const first = planUpgrade(internalOnlyRename.files, "1.0.0", releaseCatalog(loadBalancing.revision));
111
- const input = { ...internalOnlyRename.files, ...first.after };
112
- const policies = JSON.parse(input[POLICIES]);
113
- policies.policies = policies.policies.filter((p) => p.name !== LOAD_BALANCING);
114
- input[POLICIES] = JSON.stringify(policies);
115
- blocked(input, /ai-gateway-load-balancing-inbound.*previously present/);
116
- });
117
- it("does not restore a deliberately removed Internal Only policy under its new name", () => {
118
- const previous = catalog.snapshots[4];
119
- const input = {
120
- ...previous.files,
121
- [PROVENANCE]: JSON.stringify({
122
- formatVersion: 1,
123
- template: "ai-gateway",
124
- origin: { revision: previous.revision, release: "1.0.0" },
125
- appliedSteps: [],
126
- }),
127
- };
128
- const policies = JSON.parse(input[POLICIES]);
129
- policies.policies = policies.policies.filter((p) => p.name !== "ai-gateway-internal-only-inbound");
130
- input[POLICIES] = JSON.stringify(policies);
131
- blocked(input, /internal-only-inbound.*previously present/);
132
- });
133
- it("reuses historical dependency names rather than adding aliases", () => {
134
- const result = planUpgrade(files(), "1.0.0");
135
- const after = JSON.parse(result.after[AI_OAS]);
136
- const inbound = after.paths["/u/:app_id/(.*)"]["get,post,put,patch,delete,head"]["x-zuplo-route"].policies.inbound;
137
- assert.deepEqual(inbound, [
138
- "ai-gateway-configuration-loader-v2-inbound",
139
- "ai-gateway-configuration-executor-v2-inbound",
140
- ]);
141
- assert.equal(result.additions.filter((a) => a.key.includes("configuration-loader"))
142
- .length, 0);
143
- });
144
- it("does not modify an up-to-date project's bytes or create provenance", () => {
145
- assert.deepEqual(planUpgrade(latest.files, "1.0.0").after, {});
146
- });
147
- it("preserves unrelated policy text and whitespace", () => {
148
- const input = files();
149
- assert.ok(input[POLICIES].startsWith("{"));
150
- input[POLICIES] = `{\n\n${input[POLICIES].slice(1)}`;
151
- const result = planUpgrade(input, "1.0.0");
152
- assert.deepEqual(result.blockers, []);
153
- assert.ok(result.after[POLICIES].startsWith("{\n\n"));
154
- });
155
- it("blocks customized catch-all authentication", () => {
156
- blocked(change(AI_OAS, (v) => v.paths["/:app_id/(.*)"]["get,post,put,patch,delete,head"]["x-zuplo-route"].policies.inbound.unshift("my-auth")), /custom authentication/);
157
- });
158
- it("blocks reordered prerequisite chains", () => {
159
- blocked(change(AI_OAS, (v) => v.paths["/:app_id/(.*)"]["get,post,put,patch,delete,head"]["x-zuplo-route"].policies.inbound.reverse()), /supported template/);
160
- });
161
- it("blocks customized required policies", () => {
162
- blocked(change(POLICIES, (v) => {
163
- v.policies.find((p) => p.name.includes("configuration-loader")).handler.options.cacheTtlSeconds = 45;
164
- }), /required policy.*customized/);
165
- });
166
- it("blocks ambiguous canonical policy aliases", () => {
167
- blocked(change(POLICIES, (v) => v.policies.push({
168
- ...v.policies.find((p) => p.name.includes("configuration-loader")),
169
- name: "ai-gateway-configuration-loader-inbound",
170
- })), /duplicate policy identity/);
171
- });
172
- it("blocks cross-file overlapping and unsupported routes but allows disjoint literal prefixes", () => {
173
- for (const key of ["/u/custom", "/:prefix/foo", "/(.*)"]) {
174
- blocked({
175
- ...files(),
176
- "config/custom.oas.json": JSON.stringify({
177
- openapi: "3.1.0",
178
- paths: { [key]: { get: { operationId: "custom" } } },
179
- }),
180
- }, /cannot prove route/);
181
- }
182
- const result = planUpgrade({
183
- ...files(),
184
- "config/custom.oas.json": JSON.stringify({
185
- openapi: "3.1.0",
186
- paths: { "/health": { get: { operationId: "health" } } },
187
- }),
188
- }, "1.0.0");
189
- assert.deepEqual(result.blockers, []);
190
- });
191
- for (const method of ["get", "GET,POST", "Get,pOsT", " GET, POST "]) {
192
- it(`blocks duplicate operation IDs across files for ${method}`, () => {
193
- blocked({
194
- ...files(),
195
- "config/custom.oas.json": JSON.stringify({
196
- openapi: "3.1.0",
197
- paths: {
198
- "/health": {
199
- [method]: { operationId: "aiGatewayUserAppCatchAll" },
200
- },
201
- },
202
- }),
203
- }, /operationId.*already in use/);
204
- });
205
- }
206
- it("blocks custom runtime extensions and document-level security", () => {
207
- blocked({
208
- ...files(),
209
- "modules/zuplo.runtime.ts": "export function runtimeInit(runtime) { runtime.addPlugin(custom); }",
210
- }, /custom runtime/);
211
- blocked(change(AI_OAS, (v) => {
212
- v.security = [{ apiKey: [] }];
213
- }), /document-level/);
214
- });
215
- it("blocks malformed JSON and duplicate keys, retaining manual snippets", () => {
216
- for (const text of ['{"paths":', '{"policies": [], "policies": []}']) {
217
- const result = planUpgrade({ ...files(), [POLICIES]: text }, "1.0.0");
218
- assert.ok(result.blockers.length);
219
- assert.ok(result.additions.length);
220
- assert.deepEqual(result.after, {});
221
- }
222
- assert.throws(() => readJson('{"a":{"b":1,"b":2}}', "x"), /duplicate/);
223
- });
224
- it("refuses to silently restore deliberate deletion using origin or applied steps", () => {
225
- const first = planUpgrade(files(), "1.0.0");
226
- const input = { ...files(), ...first.after };
227
- const oas = JSON.parse(input[AI_OAS]);
228
- delete oas.paths["/u/:app_id/(.*)"];
229
- input[AI_OAS] = JSON.stringify(oas);
230
- blocked(input, /previously present/);
231
- const known = {
232
- ...latest.files,
233
- [AI_OAS]: JSON.stringify(oas),
234
- [PROVENANCE]: JSON.stringify({
235
- formatVersion: 1,
236
- template: "ai-gateway",
237
- origin: { revision: latest.revision, release: "1.0.0" },
238
- appliedSteps: [],
239
- }),
240
- };
241
- blocked(known, /previously present/);
242
- });
243
- it("never invents a whole-project origin for legacy projects", () => {
244
- const result = planUpgrade(files(), "1.0.0");
245
- assert.equal(JSON.parse(result.after[PROVENANCE]).origin, null);
246
- });
247
- it("fails closed for unsupported metadata formats and missing snapshots", () => {
248
- blocked({ ...files(), [PROVENANCE]: '{"formatVersion":999}' }, /formatVersion/);
249
- blocked({
250
- ...files(),
251
- [PROVENANCE]: JSON.stringify({
252
- formatVersion: 1,
253
- template: "ai-gateway",
254
- origin: { revision: "unknown", release: "1.0.0" },
255
- appliedSteps: [],
256
- }),
257
- }, /originating snapshot/);
258
- });
259
- it("supports a future assessed release, including upgrading across skipped releases", () => {
260
- const future = structuredClone(catalog);
261
- const snapshot = structuredClone(latest);
262
- snapshot.revision = "future-test-revision";
263
- const policyFile = JSON.parse(snapshot.files[POLICIES]);
264
- const policy = {
265
- name: "future-policy",
266
- handler: {
267
- module: "$import(@zuplo/runtime)",
268
- export: "FuturePolicy",
269
- options: {},
270
- },
271
- };
272
- policyFile.policies.push(policy);
273
- snapshot.files[POLICIES] = JSON.stringify(policyFile);
274
- future.snapshots.push(snapshot);
275
- future.target = snapshot.revision;
276
- future.steps.push(...catalog.steps
277
- .filter((s) => s.target === catalog.target)
278
- .map((s) => ({
279
- ...s,
280
- id: `next:${s.id}`,
281
- target: snapshot.revision,
282
- })), {
283
- id: "next:future",
284
- target: snapshot.revision,
285
- kind: "policy",
286
- key: policy.name,
287
- runtime: "release",
288
- instructions: "Add the future declaration.",
289
- });
290
- future.assessments.push({
291
- revision: snapshot.revision,
292
- classification: "additions",
293
- instructions: "New declaration only.",
294
- });
295
- const direct = planUpgrade(oldest.files, "2.0.0", future);
296
- assert.deepEqual(direct.blockers, []);
297
- assert.ok(direct.additions.some((a) => a.key === policy.name));
298
- const first = planUpgrade(original.files, "1.0.0");
299
- const next = planUpgrade({ ...original.files, ...first.after }, "2.0.0", future);
300
- assert.deepEqual(next.blockers, []);
301
- assert.deepEqual(next.additions.map((a) => a.key), [policy.name]);
302
- });
303
- it("cannot bypass a required manual migration by skipping a release", () => {
304
- const future = structuredClone(catalog);
305
- future.assessments.unshift({
306
- revision: catalog.snapshots[3].revision,
307
- classification: "manual",
308
- instructions: "Required manual authentication migration.",
309
- });
310
- const result = planUpgrade(original.files, "2.0.0", future);
311
- assert.match(result.blockers.join("\n"), /manual authentication migration/);
312
- assert.deepEqual(result.after, {});
313
- });
314
- it("checks executor prerequisites for policy-only additions", () => {
315
- const input = { ...latest.files };
316
- const policies = JSON.parse(input[POLICIES]);
317
- policies.policies = policies.policies.filter((p) => p.name !== "ai-gateway-smart-router-inbound");
318
- policies.policies.find((p) => p.name.includes("configuration-executor")).handler.export = "CustomExecutor";
319
- input[POLICIES] = JSON.stringify(policies);
320
- blocked(input, /required policy.*customized/);
321
- });
322
- it("blocks a future release classified as requiring manual changes", () => {
323
- const future = structuredClone(catalog);
324
- future.assessments[0].classification = "manual";
325
- const result = planUpgrade(files(), "2.0.0", future);
326
- assert.ok(result.blockers.length);
327
- assert.deepEqual(result.after, {});
328
- });
329
- });
330
- //# sourceMappingURL=planner.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"planner.test.js","sourceRoot":"","sources":["../../../src/source/ai-gateway/planner.test.ts"],"names":[],"mappings":"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","sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: Tests deliberately mutate fixture configuration shapes.\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport {\n AI_OAS,\n type Catalog,\n catalog,\n POLICIES,\n PROVENANCE,\n planUpgrade,\n readJson,\n} from \"./planner.js\";\n\nconst oldest = catalog.snapshots[1];\nconst original = catalog.snapshots[2];\nconst internalOnlyRename = catalog.snapshots[5];\nconst loadBalancing = catalog.snapshots[6];\nconst latest = catalog.snapshots.find((s) => s.revision === catalog.target)!;\nconst LOAD_BALANCING = \"ai-gateway-load-balancing-inbound\";\n/** The catalog as the release that made `revision` its target shipped it. */\nfunction releaseCatalog(revision: string): Catalog {\n const end = catalog.snapshots.findIndex((s) => s.revision === revision) + 1;\n const shipped = new Set(\n catalog.snapshots.slice(0, end).map((s) => s.revision)\n );\n return structuredClone({\n ...catalog,\n target: revision,\n snapshots: catalog.snapshots.slice(0, end),\n steps: catalog.steps.filter((s) => shipped.has(s.target)),\n assessments: catalog.assessments.filter((a) => shipped.has(a.revision)),\n });\n}\nconst files = () => ({ ...original.files });\nfunction change(file: string, mutate: (value: any) => void) {\n const input = files();\n const value = JSON.parse(input[file]);\n mutate(value);\n input[file] = JSON.stringify(value, null, 2);\n return input;\n}\nfunction blocked(input: Record<string, string>, expected: RegExp) {\n const before = structuredClone(input);\n const result = planUpgrade(input, \"1.0.0\");\n assert.match(result.blockers.join(\"\\n\"), expected);\n assert.deepEqual(result.after, {});\n assert.deepEqual(input, before);\n}\n\ndescribe(\"conservative versioned gateway planner\", () => {\n it(\"upgrades several historical snapshots without changing existing definitions\", () => {\n for (const snapshot of catalog.snapshots.slice(0, 4)) {\n const result = planUpgrade(snapshot.files, \"1.0.0\");\n assert.deepEqual(result.blockers, []);\n assert.ok(result.additions.length);\n const before = JSON.parse(snapshot.files[AI_OAS]);\n const after = JSON.parse(result.after[AI_OAS] ?? snapshot.files[AI_OAS]);\n for (const [key, value] of Object.entries(before.paths))\n assert.deepEqual(after.paths[key], value);\n assert.deepEqual(Object.keys(after.paths), [\n \"/u/:app_id/(.*)\",\n \"/a/:app_id/(.*)\",\n \"/:app_id/(.*)\",\n ]);\n const oldPolicies = JSON.parse(snapshot.files[POLICIES]).policies;\n const newPolicies = JSON.parse(\n result.after[POLICIES] ?? snapshot.files[POLICIES]\n ).policies;\n assert.deepEqual(newPolicies.slice(0, oldPolicies.length), oldPolicies);\n const again = planUpgrade(\n { ...snapshot.files, ...result.after },\n \"1.0.0\"\n );\n assert.deepEqual(again.blockers, []);\n assert.deepEqual(again.additions, []);\n assert.deepEqual(again.after, {});\n }\n });\n it(\"preserves the original loader defaults and rejects customized historical loaders\", () => {\n const historical = catalog.snapshots[0];\n const input = { ...historical.files };\n const result = planUpgrade(input, \"1.0.0\");\n assert.deepEqual(result.blockers, []);\n const loader = (raw: string) =>\n JSON.parse(raw).policies.find(\n (p: any) => p.name === \"ai-gateway-configuration-loader-v2-inbound\"\n );\n assert.deepEqual(loader(result.after[POLICIES]).handler.options, {});\n assert.deepEqual(loader(result.after[POLICIES]), loader(input[POLICIES]));\n const policies = JSON.parse(input[POLICIES]);\n policies.policies.find(\n (p: any) => p.name === \"ai-gateway-configuration-loader-v2-inbound\"\n ).handler.options.cacheTtlSeconds = 45;\n input[POLICIES] = JSON.stringify(policies);\n blocked(input, /required policy.*customized/);\n });\n it(\"preserves the previous template after the Internal Only rename\", () => {\n const previous = catalog.snapshots[4];\n const result = planUpgrade(\n previous.files,\n \"1.0.0\",\n releaseCatalog(internalOnlyRename.revision)\n );\n assert.deepEqual(result.blockers, []);\n assert.deepEqual(result.additions, []);\n assert.deepEqual(result.after, {});\n const historical = planUpgrade(files(), \"1.0.0\");\n assert.deepEqual(historical.blockers, []);\n assert.ok(\n !historical.additions.some((a) => a.key === \"internal-only-inbound\")\n );\n });\n it(\"adds only the Model Load Balancing declaration after the Internal Only rename\", () => {\n const release = releaseCatalog(loadBalancing.revision);\n const declaration = JSON.parse(loadBalancing.files[POLICIES]).policies.find(\n (p: any) => p.name === LOAD_BALANCING\n );\n for (const previous of [catalog.snapshots[4], internalOnlyRename]) {\n const result = planUpgrade(previous.files, \"1.0.0\", release);\n assert.deepEqual(result.blockers, []);\n assert.deepEqual(\n result.additions.map((a) => a.key),\n [LOAD_BALANCING]\n );\n assert.equal(result.after[AI_OAS], undefined);\n const before = JSON.parse(previous.files[POLICIES]).policies;\n const after = JSON.parse(result.after[POLICIES]).policies;\n assert.deepEqual(after.slice(0, -1), before);\n assert.deepEqual(after.at(-1), declaration);\n const again = planUpgrade(\n { ...previous.files, ...result.after },\n \"1.0.0\",\n release\n );\n assert.deepEqual(again.blockers, []);\n assert.deepEqual(again.additions, []);\n assert.deepEqual(again.after, {});\n }\n });\n it(\"upgrades a project that the Internal Only release already upgraded\", () => {\n const first = planUpgrade(\n original.files,\n \"1.0.0\",\n releaseCatalog(internalOnlyRename.revision)\n );\n assert.deepEqual(first.blockers, []);\n const next = planUpgrade(\n { ...original.files, ...first.after },\n \"2.0.0\",\n releaseCatalog(loadBalancing.revision)\n );\n assert.deepEqual(next.blockers, []);\n assert.deepEqual(\n next.additions.map((a) => a.key),\n [LOAD_BALANCING]\n );\n assert.ok(\n JSON.parse(next.after[PROVENANCE]).appliedSteps.includes(\n `${loadBalancing.revision}:policy:${LOAD_BALANCING}`\n )\n );\n });\n it(\"does not restore a deliberately removed Model Load Balancing declaration\", () => {\n const first = planUpgrade(\n internalOnlyRename.files,\n \"1.0.0\",\n releaseCatalog(loadBalancing.revision)\n );\n const input = { ...internalOnlyRename.files, ...first.after };\n const policies = JSON.parse(input[POLICIES]);\n policies.policies = policies.policies.filter(\n (p: any) => p.name !== LOAD_BALANCING\n );\n input[POLICIES] = JSON.stringify(policies);\n blocked(input, /ai-gateway-load-balancing-inbound.*previously present/);\n });\n it(\"does not restore a deliberately removed Internal Only policy under its new name\", () => {\n const previous = catalog.snapshots[4];\n const input: Record<string, string> = {\n ...previous.files,\n [PROVENANCE]: JSON.stringify({\n formatVersion: 1,\n template: \"ai-gateway\",\n origin: { revision: previous.revision, release: \"1.0.0\" },\n appliedSteps: [],\n }),\n };\n const policies = JSON.parse(input[POLICIES]);\n policies.policies = policies.policies.filter(\n (p: any) => p.name !== \"ai-gateway-internal-only-inbound\"\n );\n input[POLICIES] = JSON.stringify(policies);\n blocked(input, /internal-only-inbound.*previously present/);\n });\n it(\"reuses historical dependency names rather than adding aliases\", () => {\n const result = planUpgrade(files(), \"1.0.0\");\n const after = JSON.parse(result.after[AI_OAS]);\n const inbound =\n after.paths[\"/u/:app_id/(.*)\"][\"get,post,put,patch,delete,head\"][\n \"x-zuplo-route\"\n ].policies.inbound;\n assert.deepEqual(inbound, [\n \"ai-gateway-configuration-loader-v2-inbound\",\n \"ai-gateway-configuration-executor-v2-inbound\",\n ]);\n assert.equal(\n result.additions.filter((a) => a.key.includes(\"configuration-loader\"))\n .length,\n 0\n );\n });\n it(\"does not modify an up-to-date project's bytes or create provenance\", () => {\n assert.deepEqual(planUpgrade(latest.files, \"1.0.0\").after, {});\n });\n it(\"preserves unrelated policy text and whitespace\", () => {\n const input = files();\n assert.ok(input[POLICIES].startsWith(\"{\"));\n input[POLICIES] = `{\\n\\n${input[POLICIES].slice(1)}`;\n const result = planUpgrade(input, \"1.0.0\");\n assert.deepEqual(result.blockers, []);\n assert.ok(result.after[POLICIES].startsWith(\"{\\n\\n\"));\n });\n it(\"blocks customized catch-all authentication\", () => {\n blocked(\n change(AI_OAS, (v) =>\n v.paths[\"/:app_id/(.*)\"][\"get,post,put,patch,delete,head\"][\n \"x-zuplo-route\"\n ].policies.inbound.unshift(\"my-auth\")\n ),\n /custom authentication/\n );\n });\n it(\"blocks reordered prerequisite chains\", () => {\n blocked(\n change(AI_OAS, (v) =>\n v.paths[\"/:app_id/(.*)\"][\"get,post,put,patch,delete,head\"][\n \"x-zuplo-route\"\n ].policies.inbound.reverse()\n ),\n /supported template/\n );\n });\n it(\"blocks customized required policies\", () => {\n blocked(\n change(POLICIES, (v) => {\n v.policies.find((p: any) =>\n p.name.includes(\"configuration-loader\")\n ).handler.options.cacheTtlSeconds = 45;\n }),\n /required policy.*customized/\n );\n });\n it(\"blocks ambiguous canonical policy aliases\", () => {\n blocked(\n change(POLICIES, (v) =>\n v.policies.push({\n ...v.policies.find((p: any) =>\n p.name.includes(\"configuration-loader\")\n ),\n name: \"ai-gateway-configuration-loader-inbound\",\n })\n ),\n /duplicate policy identity/\n );\n });\n it(\"blocks cross-file overlapping and unsupported routes but allows disjoint literal prefixes\", () => {\n for (const key of [\"/u/custom\", \"/:prefix/foo\", \"/(.*)\"]) {\n blocked(\n {\n ...files(),\n \"config/custom.oas.json\": JSON.stringify({\n openapi: \"3.1.0\",\n paths: { [key]: { get: { operationId: \"custom\" } } },\n }),\n },\n /cannot prove route/\n );\n }\n const result = planUpgrade(\n {\n ...files(),\n \"config/custom.oas.json\": JSON.stringify({\n openapi: \"3.1.0\",\n paths: { \"/health\": { get: { operationId: \"health\" } } },\n }),\n },\n \"1.0.0\"\n );\n assert.deepEqual(result.blockers, []);\n });\n for (const method of [\"get\", \"GET,POST\", \"Get,pOsT\", \" GET, POST \"]) {\n it(`blocks duplicate operation IDs across files for ${method}`, () => {\n blocked(\n {\n ...files(),\n \"config/custom.oas.json\": JSON.stringify({\n openapi: \"3.1.0\",\n paths: {\n \"/health\": {\n [method]: { operationId: \"aiGatewayUserAppCatchAll\" },\n },\n },\n }),\n },\n /operationId.*already in use/\n );\n });\n }\n it(\"blocks custom runtime extensions and document-level security\", () => {\n blocked(\n {\n ...files(),\n \"modules/zuplo.runtime.ts\":\n \"export function runtimeInit(runtime) { runtime.addPlugin(custom); }\",\n },\n /custom runtime/\n );\n blocked(\n change(AI_OAS, (v) => {\n v.security = [{ apiKey: [] }];\n }),\n /document-level/\n );\n });\n it(\"blocks malformed JSON and duplicate keys, retaining manual snippets\", () => {\n for (const text of ['{\"paths\":', '{\"policies\": [], \"policies\": []}']) {\n const result = planUpgrade({ ...files(), [POLICIES]: text }, \"1.0.0\");\n assert.ok(result.blockers.length);\n assert.ok(result.additions.length);\n assert.deepEqual(result.after, {});\n }\n assert.throws(() => readJson('{\"a\":{\"b\":1,\"b\":2}}', \"x\"), /duplicate/);\n });\n it(\"refuses to silently restore deliberate deletion using origin or applied steps\", () => {\n const first = planUpgrade(files(), \"1.0.0\");\n const input = { ...files(), ...first.after };\n const oas = JSON.parse(input[AI_OAS]);\n delete oas.paths[\"/u/:app_id/(.*)\"];\n input[AI_OAS] = JSON.stringify(oas);\n blocked(input, /previously present/);\n const known = {\n ...latest.files,\n [AI_OAS]: JSON.stringify(oas),\n [PROVENANCE]: JSON.stringify({\n formatVersion: 1,\n template: \"ai-gateway\",\n origin: { revision: latest.revision, release: \"1.0.0\" },\n appliedSteps: [],\n }),\n };\n blocked(known, /previously present/);\n });\n it(\"never invents a whole-project origin for legacy projects\", () => {\n const result = planUpgrade(files(), \"1.0.0\");\n assert.equal(JSON.parse(result.after[PROVENANCE]).origin, null);\n });\n it(\"fails closed for unsupported metadata formats and missing snapshots\", () => {\n blocked(\n { ...files(), [PROVENANCE]: '{\"formatVersion\":999}' },\n /formatVersion/\n );\n blocked(\n {\n ...files(),\n [PROVENANCE]: JSON.stringify({\n formatVersion: 1,\n template: \"ai-gateway\",\n origin: { revision: \"unknown\", release: \"1.0.0\" },\n appliedSteps: [],\n }),\n },\n /originating snapshot/\n );\n });\n it(\"supports a future assessed release, including upgrading across skipped releases\", () => {\n const future = structuredClone(catalog);\n const snapshot = structuredClone(latest);\n snapshot.revision = \"future-test-revision\";\n const policyFile = JSON.parse(snapshot.files[POLICIES]);\n const policy = {\n name: \"future-policy\",\n handler: {\n module: \"$import(@zuplo/runtime)\",\n export: \"FuturePolicy\",\n options: {},\n },\n };\n policyFile.policies.push(policy);\n snapshot.files[POLICIES] = JSON.stringify(policyFile);\n future.snapshots.push(snapshot);\n future.target = snapshot.revision;\n future.steps.push(\n ...catalog.steps\n .filter((s) => s.target === catalog.target)\n .map((s) => ({\n ...s,\n id: `next:${s.id}`,\n target: snapshot.revision,\n })),\n {\n id: \"next:future\",\n target: snapshot.revision,\n kind: \"policy\",\n key: policy.name,\n runtime: \"release\",\n instructions: \"Add the future declaration.\",\n }\n );\n future.assessments.push({\n revision: snapshot.revision,\n classification: \"additions\",\n instructions: \"New declaration only.\",\n });\n const direct = planUpgrade(oldest.files, \"2.0.0\", future);\n assert.deepEqual(direct.blockers, []);\n assert.ok(direct.additions.some((a) => a.key === policy.name));\n const first = planUpgrade(original.files, \"1.0.0\");\n const next = planUpgrade(\n { ...original.files, ...first.after },\n \"2.0.0\",\n future\n );\n assert.deepEqual(next.blockers, []);\n assert.deepEqual(\n next.additions.map((a) => a.key),\n [policy.name]\n );\n });\n it(\"cannot bypass a required manual migration by skipping a release\", () => {\n const future = structuredClone(catalog);\n future.assessments.unshift({\n revision: catalog.snapshots[3].revision,\n classification: \"manual\",\n instructions: \"Required manual authentication migration.\",\n });\n const result = planUpgrade(original.files, \"2.0.0\", future);\n assert.match(result.blockers.join(\"\\n\"), /manual authentication migration/);\n assert.deepEqual(result.after, {});\n });\n\n it(\"checks executor prerequisites for policy-only additions\", () => {\n const input = { ...latest.files };\n const policies = JSON.parse(input[POLICIES]);\n policies.policies = policies.policies.filter(\n (p: any) => p.name !== \"ai-gateway-smart-router-inbound\"\n );\n policies.policies.find((p: any) =>\n p.name.includes(\"configuration-executor\")\n ).handler.export = \"CustomExecutor\";\n input[POLICIES] = JSON.stringify(policies);\n blocked(input, /required policy.*customized/);\n });\n\n it(\"blocks a future release classified as requiring manual changes\", () => {\n const future = structuredClone(catalog);\n future.assessments[0].classification = \"manual\";\n const result = planUpgrade(files(), \"2.0.0\", future);\n assert.ok(result.blockers.length);\n assert.deepEqual(result.after, {});\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=release.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"release.test.d.ts","sourceRoot":"","sources":["../../../src/source/ai-gateway/release.test.ts"],"names":[],"mappings":""}
@@ -1,62 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
- import { tmpdir } from "node:os";
4
- import path from "node:path";
5
- import { describe, it } from "node:test";
6
- import { catalog, planUpgrade } from "./planner.js";
7
- import { checkRelease, installedRuntime, runtimeBlocker } from "./release.js";
8
- describe("AI Gateway release safety", () => {
9
- it("requires matching stable CLI, scaffolder, and zuplo releases", async () => {
10
- const requests = [];
11
- const fetcher = async (url) => {
12
- requests.push(String(url));
13
- return Response.json({ version: "1.2.3" });
14
- };
15
- assert.deepEqual(await checkRelease("1.2.3", fetcher), { latest: "1.2.3" });
16
- assert.equal(requests.length, 3);
17
- assert.match((await checkRelease("1.2.2", fetcher)).blocker, /Install zuplo@1.2.3/);
18
- });
19
- it("fails closed for offline, invalid, prerelease, and partial publication", async () => {
20
- assert.match((await checkRelease("1.2.3", async () => {
21
- throw new Error("offline");
22
- })).blocker, /could not be verified/);
23
- for (const version of ["bad", "1.2.3-dev.1"])
24
- assert.ok((await checkRelease("1.2.3", async () => Response.json({ version })))
25
- .blocker);
26
- assert.match((await checkRelease("1.2.3", async (url) => Response.json({
27
- version: String(url).includes("create-zuplo-api")
28
- ? "1.2.2"
29
- : "1.2.3",
30
- }))).blocker, /inconsistent/);
31
- });
32
- it("resolves the project's import-only runtime rather than the updater's runtime", async () => {
33
- const dir = await mkdtemp(path.join(tmpdir(), "gateway-runtime-resolution-"));
34
- try {
35
- await mkdir(path.join(dir, "node_modules/zuplo"), { recursive: true });
36
- const runtime = path.join(dir, "node_modules/zuplo/node_modules/@zuplo/runtime");
37
- await mkdir(path.join(runtime, "dist"), { recursive: true });
38
- await writeFile(path.join(dir, "package.json"), '{"name":"customer"}');
39
- await writeFile(path.join(dir, "node_modules/zuplo/package.json"), '{"name":"zuplo","version":"1.2.3"}');
40
- await writeFile(path.join(runtime, "package.json"), JSON.stringify({
41
- name: "@zuplo/runtime",
42
- version: "1.2.3",
43
- exports: { ".": { import: "./dist/index.js" } },
44
- }));
45
- await writeFile(path.join(runtime, "dist/index.js"), "throw new Error('must not execute customer runtime');");
46
- assert.equal((await installedRuntime(dir)).version, "1.2.3");
47
- await rm(path.join(runtime, "dist/index.js"));
48
- await assert.rejects(installedRuntime(dir), /ENOENT/);
49
- }
50
- finally {
51
- await rm(dir, { recursive: true, force: true });
52
- }
53
- });
54
- it("requires the project's installed runtime to satisfy each step", () => {
55
- const plan = planUpgrade(catalog.snapshots[1].files, "1.2.3");
56
- assert.equal(runtimeBlocker("1.2.3", plan), undefined);
57
- assert.match(runtimeBlocker("1.2.2", plan), /Upgrade dependencies separately/);
58
- assert.ok(runtimeBlocker("1.2.4-dev.1", plan));
59
- assert.ok(runtimeBlocker("0.0.0", { ...plan, release: "0.0.0" }));
60
- });
61
- });
62
- //# sourceMappingURL=release.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"release.test.js","sourceRoot":"","sources":["../../../src/source/ai-gateway/release.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\";\nimport { mkdir, mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { describe, it } from \"node:test\";\nimport { catalog, planUpgrade } from \"./planner.js\";\nimport { checkRelease, installedRuntime, runtimeBlocker } from \"./release.js\";\n\ndescribe(\"AI Gateway release safety\", () => {\n it(\"requires matching stable CLI, scaffolder, and zuplo releases\", async () => {\n const requests: string[] = [];\n const fetcher: typeof fetch = async (url) => {\n requests.push(String(url));\n return Response.json({ version: \"1.2.3\" });\n };\n assert.deepEqual(await checkRelease(\"1.2.3\", fetcher), { latest: \"1.2.3\" });\n assert.equal(requests.length, 3);\n assert.match(\n (await checkRelease(\"1.2.2\", fetcher)).blocker!,\n /Install zuplo@1.2.3/\n );\n });\n it(\"fails closed for offline, invalid, prerelease, and partial publication\", async () => {\n assert.match(\n (\n await checkRelease(\"1.2.3\", async () => {\n throw new Error(\"offline\");\n })\n ).blocker!,\n /could not be verified/\n );\n for (const version of [\"bad\", \"1.2.3-dev.1\"])\n assert.ok(\n (await checkRelease(\"1.2.3\", async () => Response.json({ version })))\n .blocker\n );\n assert.match(\n (\n await checkRelease(\"1.2.3\", async (url) =>\n Response.json({\n version: String(url).includes(\"create-zuplo-api\")\n ? \"1.2.2\"\n : \"1.2.3\",\n })\n )\n ).blocker!,\n /inconsistent/\n );\n });\n it(\"resolves the project's import-only runtime rather than the updater's runtime\", async () => {\n const dir = await mkdtemp(\n path.join(tmpdir(), \"gateway-runtime-resolution-\")\n );\n try {\n await mkdir(path.join(dir, \"node_modules/zuplo\"), { recursive: true });\n const runtime = path.join(\n dir,\n \"node_modules/zuplo/node_modules/@zuplo/runtime\"\n );\n await mkdir(path.join(runtime, \"dist\"), { recursive: true });\n await writeFile(path.join(dir, \"package.json\"), '{\"name\":\"customer\"}');\n await writeFile(\n path.join(dir, \"node_modules/zuplo/package.json\"),\n '{\"name\":\"zuplo\",\"version\":\"1.2.3\"}'\n );\n await writeFile(\n path.join(runtime, \"package.json\"),\n JSON.stringify({\n name: \"@zuplo/runtime\",\n version: \"1.2.3\",\n exports: { \".\": { import: \"./dist/index.js\" } },\n })\n );\n await writeFile(\n path.join(runtime, \"dist/index.js\"),\n \"throw new Error('must not execute customer runtime');\"\n );\n assert.equal((await installedRuntime(dir)).version, \"1.2.3\");\n await rm(path.join(runtime, \"dist/index.js\"));\n await assert.rejects(installedRuntime(dir), /ENOENT/);\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n });\n\n it(\"requires the project's installed runtime to satisfy each step\", () => {\n const plan = planUpgrade(catalog.snapshots[1].files, \"1.2.3\");\n assert.equal(runtimeBlocker(\"1.2.3\", plan), undefined);\n assert.match(\n runtimeBlocker(\"1.2.2\", plan)!,\n /Upgrade dependencies separately/\n );\n assert.ok(runtimeBlocker(\"1.2.4-dev.1\", plan));\n assert.ok(runtimeBlocker(\"0.0.0\", { ...plan, release: \"0.0.0\" }));\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=invoke-test.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"invoke-test.test.d.ts","sourceRoot":"","sources":["../../src/test/invoke-test.test.ts"],"names":[],"mappings":""}