@zuplo/cli 7.11.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 (303) hide show
  1. package/node_modules/@hono/node-server/README.md +2 -0
  2. package/node_modules/@hono/node-server/dist/index.cjs +1 -1
  3. package/node_modules/@hono/node-server/dist/index.mjs +1 -1
  4. package/node_modules/@hono/node-server/dist/serve-static.cjs +2 -1
  5. package/node_modules/@hono/node-server/dist/serve-static.mjs +2 -1
  6. package/node_modules/@hono/node-server/package.json +1 -1
  7. package/node_modules/@posthog/core/dist/metrics/index.d.ts +9 -0
  8. package/node_modules/@posthog/core/dist/metrics/index.d.ts.map +1 -1
  9. package/node_modules/@posthog/core/dist/metrics/index.js +38 -3
  10. package/node_modules/@posthog/core/dist/metrics/index.mjs +38 -3
  11. package/node_modules/@posthog/core/dist/metrics/types.d.ts +7 -2
  12. package/node_modules/@posthog/core/dist/metrics/types.d.ts.map +1 -1
  13. package/node_modules/@posthog/core/dist/traces/ids.d.ts.map +1 -1
  14. package/node_modules/@posthog/core/dist/traces/ids.js +2 -2
  15. package/node_modules/@posthog/core/dist/traces/ids.mjs +2 -2
  16. package/node_modules/@posthog/core/package.json +2 -2
  17. package/node_modules/@posthog/core/src/metrics/index.spec.ts +75 -0
  18. package/node_modules/@posthog/core/src/metrics/index.ts +60 -0
  19. package/node_modules/@posthog/core/src/metrics/types.ts +7 -1
  20. package/node_modules/@posthog/core/src/traces/ids.ts +4 -2
  21. package/node_modules/@posthog/types/dist/capture-metric.d.ts +10 -0
  22. package/node_modules/@posthog/types/dist/capture-metric.d.ts.map +1 -1
  23. package/node_modules/@posthog/types/dist/index.d.ts +1 -1
  24. package/node_modules/@posthog/types/dist/index.d.ts.map +1 -1
  25. package/node_modules/@posthog/types/package.json +1 -1
  26. package/node_modules/@posthog/types/src/capture-metric.ts +11 -0
  27. package/node_modules/@posthog/types/src/index.ts +1 -0
  28. package/node_modules/@zuplo/core/customer.cli.minified.js +2 -2
  29. package/node_modules/@zuplo/core/index.minified.js +2 -2
  30. package/node_modules/@zuplo/core/package.json +1 -1
  31. package/node_modules/@zuplo/graphql/package.json +1 -1
  32. package/node_modules/@zuplo/openapi-tools/package.json +5 -2
  33. package/node_modules/@zuplo/otel/package.json +1 -1
  34. package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js → chunk-CDEAY3VY.js} +2 -2
  35. package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js +37 -0
  36. package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js.map +1 -0
  37. package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js → chunk-NUVXDVLJ.js} +2 -2
  38. package/node_modules/@zuplo/runtime/out/esm/{chunk-6YPRGG62.js → chunk-RHU3Z7DA.js} +108 -108
  39. package/node_modules/@zuplo/runtime/out/esm/chunk-RHU3Z7DA.js.map +1 -0
  40. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  41. package/node_modules/@zuplo/runtime/out/esm/internal/index.js +1 -1
  42. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  43. package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
  44. package/node_modules/@zuplo/runtime/out/esm/sdks/aws/index.js +1 -1
  45. package/node_modules/@zuplo/runtime/out/types/index.d.ts +15 -24
  46. package/node_modules/@zuplo/runtime/out/types/internal/index.d.ts +14 -0
  47. package/node_modules/@zuplo/runtime/package.json +1 -1
  48. package/package.json +15 -12
  49. package/dist/__tests__/archive-utils.test.d.ts +0 -2
  50. package/dist/__tests__/archive-utils.test.d.ts.map +0 -1
  51. package/dist/__tests__/archive-utils.test.js +0 -50
  52. package/dist/__tests__/archive-utils.test.js.map +0 -1
  53. package/dist/__tests__/import-openapi.test.d.ts +0 -2
  54. package/dist/__tests__/import-openapi.test.d.ts.map +0 -1
  55. package/dist/__tests__/import-openapi.test.js +0 -251
  56. package/dist/__tests__/import-openapi.test.js.map +0 -1
  57. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts +0 -2
  58. package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts.map +0 -1
  59. package/dist/__tests__/integration/confirm-linked-config.integration.test.js +0 -202
  60. package/dist/__tests__/integration/confirm-linked-config.integration.test.js.map +0 -1
  61. package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts +0 -2
  62. package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts.map +0 -1
  63. package/dist/__tests__/integration/confirm-production-deploy.integration.test.js +0 -184
  64. package/dist/__tests__/integration/confirm-production-deploy.integration.test.js.map +0 -1
  65. package/dist/__tests__/integration/custom-domain.integration.test.d.ts +0 -2
  66. package/dist/__tests__/integration/custom-domain.integration.test.d.ts.map +0 -1
  67. package/dist/__tests__/integration/custom-domain.integration.test.js +0 -563
  68. package/dist/__tests__/integration/custom-domain.integration.test.js.map +0 -1
  69. package/dist/__tests__/integration/delete.integration.test.d.ts +0 -2
  70. package/dist/__tests__/integration/delete.integration.test.d.ts.map +0 -1
  71. package/dist/__tests__/integration/delete.integration.test.js +0 -262
  72. package/dist/__tests__/integration/delete.integration.test.js.map +0 -1
  73. package/dist/__tests__/integration/deploy.integration.test.d.ts +0 -2
  74. package/dist/__tests__/integration/deploy.integration.test.d.ts.map +0 -1
  75. package/dist/__tests__/integration/deploy.integration.test.js +0 -519
  76. package/dist/__tests__/integration/deploy.integration.test.js.map +0 -1
  77. package/dist/__tests__/integration/get-project-param.integration.test.d.ts +0 -2
  78. package/dist/__tests__/integration/get-project-param.integration.test.d.ts.map +0 -1
  79. package/dist/__tests__/integration/get-project-param.integration.test.js +0 -305
  80. package/dist/__tests__/integration/get-project-param.integration.test.js.map +0 -1
  81. package/dist/__tests__/integration/info.integration.test.d.ts +0 -2
  82. package/dist/__tests__/integration/info.integration.test.d.ts.map +0 -1
  83. package/dist/__tests__/integration/info.integration.test.js +0 -293
  84. package/dist/__tests__/integration/info.integration.test.js.map +0 -1
  85. package/dist/__tests__/integration/jest-mocks-setup.d.ts +0 -2
  86. package/dist/__tests__/integration/jest-mocks-setup.d.ts.map +0 -1
  87. package/dist/__tests__/integration/jest-mocks-setup.js +0 -104
  88. package/dist/__tests__/integration/jest-mocks-setup.js.map +0 -1
  89. package/dist/__tests__/integration/jest-setup.d.ts +0 -2
  90. package/dist/__tests__/integration/jest-setup.d.ts.map +0 -1
  91. package/dist/__tests__/integration/jest-setup.js +0 -12
  92. package/dist/__tests__/integration/jest-setup.js.map +0 -1
  93. package/dist/__tests__/integration/link.integration.test.d.ts +0 -2
  94. package/dist/__tests__/integration/link.integration.test.d.ts.map +0 -1
  95. package/dist/__tests__/integration/link.integration.test.js +0 -395
  96. package/dist/__tests__/integration/link.integration.test.js.map +0 -1
  97. package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts +0 -2
  98. package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts.map +0 -1
  99. package/dist/__tests__/integration/linked-config-cascade.integration.test.js +0 -179
  100. package/dist/__tests__/integration/linked-config-cascade.integration.test.js.map +0 -1
  101. package/dist/__tests__/integration/list.integration.test.d.ts +0 -2
  102. package/dist/__tests__/integration/list.integration.test.d.ts.map +0 -1
  103. package/dist/__tests__/integration/list.integration.test.js +0 -300
  104. package/dist/__tests__/integration/list.integration.test.js.map +0 -1
  105. package/dist/__tests__/integration/source-upgrade.integration.test.d.ts +0 -2
  106. package/dist/__tests__/integration/source-upgrade.integration.test.d.ts.map +0 -1
  107. package/dist/__tests__/integration/source-upgrade.integration.test.js +0 -100
  108. package/dist/__tests__/integration/source-upgrade.integration.test.js.map +0 -1
  109. package/dist/__tests__/integration/test-utils.d.ts +0 -30
  110. package/dist/__tests__/integration/test-utils.d.ts.map +0 -1
  111. package/dist/__tests__/integration/test-utils.js +0 -82
  112. package/dist/__tests__/integration/test-utils.js.map +0 -1
  113. package/dist/__tests__/integration/tunnel.integration.test.d.ts +0 -2
  114. package/dist/__tests__/integration/tunnel.integration.test.d.ts.map +0 -1
  115. package/dist/__tests__/integration/tunnel.integration.test.js +0 -486
  116. package/dist/__tests__/integration/tunnel.integration.test.js.map +0 -1
  117. package/dist/__tests__/integration/variable.integration.test.d.ts +0 -2
  118. package/dist/__tests__/integration/variable.integration.test.d.ts.map +0 -1
  119. package/dist/__tests__/integration/variable.integration.test.js +0 -258
  120. package/dist/__tests__/integration/variable.integration.test.js.map +0 -1
  121. package/dist/__tests__/integration/whoami.integration.test.d.ts +0 -2
  122. package/dist/__tests__/integration/whoami.integration.test.d.ts.map +0 -1
  123. package/dist/__tests__/integration/whoami.integration.test.js +0 -116
  124. package/dist/__tests__/integration/whoami.integration.test.js.map +0 -1
  125. package/dist/__tests__/outdated.test.d.ts +0 -2
  126. package/dist/__tests__/outdated.test.d.ts.map +0 -1
  127. package/dist/__tests__/outdated.test.js +0 -67
  128. package/dist/__tests__/outdated.test.js.map +0 -1
  129. package/dist/__tests__/populate.test.d.ts +0 -2
  130. package/dist/__tests__/populate.test.d.ts.map +0 -1
  131. package/dist/__tests__/populate.test.js +0 -445
  132. package/dist/__tests__/populate.test.js.map +0 -1
  133. package/dist/__tests__/tsconfig-upgrader.test.d.ts +0 -2
  134. package/dist/__tests__/tsconfig-upgrader.test.d.ts.map +0 -1
  135. package/dist/__tests__/tsconfig-upgrader.test.js +0 -31
  136. package/dist/__tests__/tsconfig-upgrader.test.js.map +0 -1
  137. package/dist/ca-certificate/validation.test.d.ts +0 -2
  138. package/dist/ca-certificate/validation.test.d.ts.map +0 -1
  139. package/dist/ca-certificate/validation.test.js +0 -131
  140. package/dist/ca-certificate/validation.test.js.map +0 -1
  141. package/dist/common/analytics/cli-invocation.test.d.ts +0 -2
  142. package/dist/common/analytics/cli-invocation.test.d.ts.map +0 -1
  143. package/dist/common/analytics/cli-invocation.test.js +0 -51
  144. package/dist/common/analytics/cli-invocation.test.js.map +0 -1
  145. package/dist/common/analytics/package-manager.test.d.ts +0 -2
  146. package/dist/common/analytics/package-manager.test.d.ts.map +0 -1
  147. package/dist/common/analytics/package-manager.test.js +0 -163
  148. package/dist/common/analytics/package-manager.test.js.map +0 -1
  149. package/dist/common/cli-dispatcher.test.d.ts +0 -2
  150. package/dist/common/cli-dispatcher.test.d.ts.map +0 -1
  151. package/dist/common/cli-dispatcher.test.js +0 -80
  152. package/dist/common/cli-dispatcher.test.js.map +0 -1
  153. package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts +0 -2
  154. package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts.map +0 -1
  155. package/dist/common/middleware/check-pnpm-lifecycle.test.js +0 -125
  156. package/dist/common/middleware/check-pnpm-lifecycle.test.js.map +0 -1
  157. package/dist/common/middleware/get-environment-param.test.d.ts +0 -2
  158. package/dist/common/middleware/get-environment-param.test.d.ts.map +0 -1
  159. package/dist/common/middleware/get-environment-param.test.js +0 -57
  160. package/dist/common/middleware/get-environment-param.test.js.map +0 -1
  161. package/dist/common/read-linked-config.test.d.ts +0 -2
  162. package/dist/common/read-linked-config.test.d.ts.map +0 -1
  163. package/dist/common/read-linked-config.test.js +0 -363
  164. package/dist/common/read-linked-config.test.js.map +0 -1
  165. package/dist/common/terminal.test.d.ts +0 -2
  166. package/dist/common/terminal.test.d.ts.map +0 -1
  167. package/dist/common/terminal.test.js +0 -101
  168. package/dist/common/terminal.test.js.map +0 -1
  169. package/dist/common/utils/build-environment-prompt-choices.test.d.ts +0 -2
  170. package/dist/common/utils/build-environment-prompt-choices.test.d.ts.map +0 -1
  171. package/dist/common/utils/build-environment-prompt-choices.test.js +0 -97
  172. package/dist/common/utils/build-environment-prompt-choices.test.js.map +0 -1
  173. package/dist/common/utils/format-environment-type.test.d.ts +0 -2
  174. package/dist/common/utils/format-environment-type.test.d.ts.map +0 -1
  175. package/dist/common/utils/format-environment-type.test.js +0 -32
  176. package/dist/common/utils/format-environment-type.test.js.map +0 -1
  177. package/dist/common/utils/pnpm-lifecycle.test.d.ts +0 -2
  178. package/dist/common/utils/pnpm-lifecycle.test.d.ts.map +0 -1
  179. package/dist/common/utils/pnpm-lifecycle.test.js +0 -196
  180. package/dist/common/utils/pnpm-lifecycle.test.js.map +0 -1
  181. package/dist/common/utils/pretty-print-environment-prompt.test.d.ts +0 -2
  182. package/dist/common/utils/pretty-print-environment-prompt.test.d.ts.map +0 -1
  183. package/dist/common/utils/pretty-print-environment-prompt.test.js +0 -42
  184. package/dist/common/utils/pretty-print-environment-prompt.test.js.map +0 -1
  185. package/dist/common/utils/sort-environments-for-prompt.test.d.ts +0 -2
  186. package/dist/common/utils/sort-environments-for-prompt.test.d.ts.map +0 -1
  187. package/dist/common/utils/sort-environments-for-prompt.test.js +0 -82
  188. package/dist/common/utils/sort-environments-for-prompt.test.js.map +0 -1
  189. package/dist/common/utils/stringify-config.test.d.ts +0 -2
  190. package/dist/common/utils/stringify-config.test.d.ts.map +0 -1
  191. package/dist/common/utils/stringify-config.test.js +0 -80
  192. package/dist/common/utils/stringify-config.test.js.map +0 -1
  193. package/dist/common/validators/argument-validators.spec.d.ts +0 -2
  194. package/dist/common/validators/argument-validators.spec.d.ts.map +0 -1
  195. package/dist/common/validators/argument-validators.spec.js +0 -181
  196. package/dist/common/validators/argument-validators.spec.js.map +0 -1
  197. package/dist/common/worker-output.test.d.ts +0 -2
  198. package/dist/common/worker-output.test.d.ts.map +0 -1
  199. package/dist/common/worker-output.test.js +0 -32
  200. package/dist/common/worker-output.test.js.map +0 -1
  201. package/dist/deploy/archive.local-registry.test.d.ts +0 -2
  202. package/dist/deploy/archive.local-registry.test.d.ts.map +0 -1
  203. package/dist/deploy/archive.local-registry.test.js +0 -100
  204. package/dist/deploy/archive.local-registry.test.js.map +0 -1
  205. package/dist/deploy/archive.test.d.ts +0 -2
  206. package/dist/deploy/archive.test.d.ts.map +0 -1
  207. package/dist/deploy/archive.test.js +0 -248
  208. package/dist/deploy/archive.test.js.map +0 -1
  209. package/dist/deploy/classify-build-probe.test.d.ts +0 -2
  210. package/dist/deploy/classify-build-probe.test.d.ts.map +0 -1
  211. package/dist/deploy/classify-build-probe.test.js +0 -51
  212. package/dist/deploy/classify-build-probe.test.js.map +0 -1
  213. package/dist/deploy/poll-deployment.test.d.ts +0 -2
  214. package/dist/deploy/poll-deployment.test.d.ts.map +0 -1
  215. package/dist/deploy/poll-deployment.test.js +0 -158
  216. package/dist/deploy/poll-deployment.test.js.map +0 -1
  217. package/dist/dev/zuplo-local-gitignore.test.d.ts +0 -2
  218. package/dist/dev/zuplo-local-gitignore.test.d.ts.map +0 -1
  219. package/dist/dev/zuplo-local-gitignore.test.js +0 -58
  220. package/dist/dev/zuplo-local-gitignore.test.js.map +0 -1
  221. package/dist/editor/e2e/editor.spec.d.ts +0 -2
  222. package/dist/editor/e2e/editor.spec.d.ts.map +0 -1
  223. package/dist/editor/e2e/editor.spec.js +0 -44
  224. package/dist/editor/e2e/editor.spec.js.map +0 -1
  225. package/dist/link/project-type.test.d.ts +0 -2
  226. package/dist/link/project-type.test.d.ts.map +0 -1
  227. package/dist/link/project-type.test.js +0 -225
  228. package/dist/link/project-type.test.js.map +0 -1
  229. package/dist/lint/resolve-binary.test.d.ts +0 -2
  230. package/dist/lint/resolve-binary.test.d.ts.map +0 -1
  231. package/dist/lint/resolve-binary.test.js +0 -155
  232. package/dist/lint/resolve-binary.test.js.map +0 -1
  233. package/dist/open-api/convert/handler.spec.d.ts +0 -2
  234. package/dist/open-api/convert/handler.spec.d.ts.map +0 -1
  235. package/dist/open-api/convert/handler.spec.js +0 -301
  236. package/dist/open-api/convert/handler.spec.js.map +0 -1
  237. package/dist/open-api/merge/handler.spec.d.ts +0 -2
  238. package/dist/open-api/merge/handler.spec.d.ts.map +0 -1
  239. package/dist/open-api/merge/handler.spec.js +0 -673
  240. package/dist/open-api/merge/handler.spec.js.map +0 -1
  241. package/dist/open-api/overlay/handler.spec.d.ts +0 -2
  242. package/dist/open-api/overlay/handler.spec.d.ts.map +0 -1
  243. package/dist/open-api/overlay/handler.spec.js +0 -346
  244. package/dist/open-api/overlay/handler.spec.js.map +0 -1
  245. package/dist/source/ai-gateway/files.test.d.ts +0 -2
  246. package/dist/source/ai-gateway/files.test.d.ts.map +0 -1
  247. package/dist/source/ai-gateway/files.test.js +0 -135
  248. package/dist/source/ai-gateway/files.test.js.map +0 -1
  249. package/dist/source/ai-gateway/handler.test.d.ts +0 -2
  250. package/dist/source/ai-gateway/handler.test.d.ts.map +0 -1
  251. package/dist/source/ai-gateway/handler.test.js +0 -113
  252. package/dist/source/ai-gateway/handler.test.js.map +0 -1
  253. package/dist/source/ai-gateway/package.test.d.ts +0 -2
  254. package/dist/source/ai-gateway/package.test.d.ts.map +0 -1
  255. package/dist/source/ai-gateway/package.test.js +0 -30
  256. package/dist/source/ai-gateway/package.test.js.map +0 -1
  257. package/dist/source/ai-gateway/planner.test.d.ts +0 -2
  258. package/dist/source/ai-gateway/planner.test.d.ts.map +0 -1
  259. package/dist/source/ai-gateway/planner.test.js +0 -330
  260. package/dist/source/ai-gateway/planner.test.js.map +0 -1
  261. package/dist/source/ai-gateway/release.test.d.ts +0 -2
  262. package/dist/source/ai-gateway/release.test.d.ts.map +0 -1
  263. package/dist/source/ai-gateway/release.test.js +0 -62
  264. package/dist/source/ai-gateway/release.test.js.map +0 -1
  265. package/dist/test/invoke-test.test.d.ts +0 -2
  266. package/dist/test/invoke-test.test.d.ts.map +0 -1
  267. package/dist/test/invoke-test.test.js +0 -150
  268. package/dist/test/invoke-test.test.js.map +0 -1
  269. package/dist/test/test-files.test.d.ts +0 -2
  270. package/dist/test/test-files.test.d.ts.map +0 -1
  271. package/dist/test/test-files.test.js +0 -57
  272. package/dist/test/test-files.test.js.map +0 -1
  273. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts +0 -2
  274. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts.map +0 -1
  275. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js +0 -289
  276. package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js.map +0 -1
  277. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts +0 -2
  278. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts.map +0 -1
  279. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js +0 -181
  280. package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js.map +0 -1
  281. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts +0 -2
  282. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts.map +0 -1
  283. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js +0 -399
  284. package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js.map +0 -1
  285. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts +0 -2
  286. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts.map +0 -1
  287. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js +0 -779
  288. package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js.map +0 -1
  289. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts +0 -2
  290. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts.map +0 -1
  291. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js +0 -269
  292. package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js.map +0 -1
  293. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts +0 -2
  294. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts.map +0 -1
  295. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js +0 -93
  296. package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js.map +0 -1
  297. package/node_modules/@zuplo/runtime/out/esm/chunk-6YPRGG62.js.map +0 -1
  298. package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js +0 -37
  299. package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js.map +0 -1
  300. /package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js.map → chunk-CDEAY3VY.js.map} +0 -0
  301. /package/node_modules/@zuplo/runtime/out/esm/{chunk-PBDT4FDO.js.LEGAL.txt → chunk-LVSZ3WTO.js.LEGAL.txt} +0 -0
  302. /package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js.map → chunk-NUVXDVLJ.js.map} +0 -0
  303. /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":""}