@zuplo/cli 7.11.0 → 7.11.3
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.
- package/node_modules/@hono/node-server/README.md +2 -0
- package/node_modules/@hono/node-server/dist/index.cjs +1 -1
- package/node_modules/@hono/node-server/dist/index.mjs +1 -1
- package/node_modules/@hono/node-server/dist/serve-static.cjs +2 -1
- package/node_modules/@hono/node-server/dist/serve-static.mjs +2 -1
- package/node_modules/@hono/node-server/package.json +1 -1
- package/node_modules/@posthog/core/dist/metrics/index.d.ts +9 -0
- package/node_modules/@posthog/core/dist/metrics/index.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/metrics/index.js +38 -3
- package/node_modules/@posthog/core/dist/metrics/index.mjs +38 -3
- package/node_modules/@posthog/core/dist/metrics/types.d.ts +7 -2
- package/node_modules/@posthog/core/dist/metrics/types.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/traces/ids.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/traces/ids.js +2 -2
- package/node_modules/@posthog/core/dist/traces/ids.mjs +2 -2
- package/node_modules/@posthog/core/package.json +2 -2
- package/node_modules/@posthog/core/src/metrics/index.spec.ts +75 -0
- package/node_modules/@posthog/core/src/metrics/index.ts +60 -0
- package/node_modules/@posthog/core/src/metrics/types.ts +7 -1
- package/node_modules/@posthog/core/src/traces/ids.ts +4 -2
- package/node_modules/@posthog/types/dist/capture-metric.d.ts +10 -0
- package/node_modules/@posthog/types/dist/capture-metric.d.ts.map +1 -1
- package/node_modules/@posthog/types/dist/index.d.ts +1 -1
- package/node_modules/@posthog/types/dist/index.d.ts.map +1 -1
- package/node_modules/@posthog/types/package.json +1 -1
- package/node_modules/@posthog/types/src/capture-metric.ts +11 -0
- package/node_modules/@posthog/types/src/index.ts +1 -0
- package/node_modules/@zuplo/core/customer.cli.minified.js +80 -80
- package/node_modules/@zuplo/core/index.minified.js +85 -85
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +5 -2
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js → chunk-CDEAY3VY.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js +37 -0
- package/node_modules/@zuplo/runtime/out/esm/chunk-LVSZ3WTO.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js → chunk-NUVXDVLJ.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/{chunk-6YPRGG62.js → chunk-TPYCFLC7.js} +109 -109
- package/node_modules/@zuplo/runtime/out/esm/chunk-TPYCFLC7.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/internal/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/sdks/aws/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/types/index.d.ts +43 -43
- package/node_modules/@zuplo/runtime/out/types/internal/index.d.ts +14 -0
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/package.json +15 -12
- package/dist/__tests__/archive-utils.test.d.ts +0 -2
- package/dist/__tests__/archive-utils.test.d.ts.map +0 -1
- package/dist/__tests__/archive-utils.test.js +0 -50
- package/dist/__tests__/archive-utils.test.js.map +0 -1
- package/dist/__tests__/import-openapi.test.d.ts +0 -2
- package/dist/__tests__/import-openapi.test.d.ts.map +0 -1
- package/dist/__tests__/import-openapi.test.js +0 -251
- package/dist/__tests__/import-openapi.test.js.map +0 -1
- package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/confirm-linked-config.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/confirm-linked-config.integration.test.js +0 -202
- package/dist/__tests__/integration/confirm-linked-config.integration.test.js.map +0 -1
- package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/confirm-production-deploy.integration.test.js +0 -184
- package/dist/__tests__/integration/confirm-production-deploy.integration.test.js.map +0 -1
- package/dist/__tests__/integration/custom-domain.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/custom-domain.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/custom-domain.integration.test.js +0 -563
- package/dist/__tests__/integration/custom-domain.integration.test.js.map +0 -1
- package/dist/__tests__/integration/delete.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/delete.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/delete.integration.test.js +0 -262
- package/dist/__tests__/integration/delete.integration.test.js.map +0 -1
- package/dist/__tests__/integration/deploy.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/deploy.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/deploy.integration.test.js +0 -519
- package/dist/__tests__/integration/deploy.integration.test.js.map +0 -1
- package/dist/__tests__/integration/get-project-param.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/get-project-param.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/get-project-param.integration.test.js +0 -305
- package/dist/__tests__/integration/get-project-param.integration.test.js.map +0 -1
- package/dist/__tests__/integration/info.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/info.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/info.integration.test.js +0 -293
- package/dist/__tests__/integration/info.integration.test.js.map +0 -1
- package/dist/__tests__/integration/jest-mocks-setup.d.ts +0 -2
- package/dist/__tests__/integration/jest-mocks-setup.d.ts.map +0 -1
- package/dist/__tests__/integration/jest-mocks-setup.js +0 -104
- package/dist/__tests__/integration/jest-mocks-setup.js.map +0 -1
- package/dist/__tests__/integration/jest-setup.d.ts +0 -2
- package/dist/__tests__/integration/jest-setup.d.ts.map +0 -1
- package/dist/__tests__/integration/jest-setup.js +0 -12
- package/dist/__tests__/integration/jest-setup.js.map +0 -1
- package/dist/__tests__/integration/link.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/link.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/link.integration.test.js +0 -395
- package/dist/__tests__/integration/link.integration.test.js.map +0 -1
- package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/linked-config-cascade.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/linked-config-cascade.integration.test.js +0 -179
- package/dist/__tests__/integration/linked-config-cascade.integration.test.js.map +0 -1
- package/dist/__tests__/integration/list.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/list.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/list.integration.test.js +0 -300
- package/dist/__tests__/integration/list.integration.test.js.map +0 -1
- package/dist/__tests__/integration/source-upgrade.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/source-upgrade.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/source-upgrade.integration.test.js +0 -100
- package/dist/__tests__/integration/source-upgrade.integration.test.js.map +0 -1
- package/dist/__tests__/integration/test-utils.d.ts +0 -30
- package/dist/__tests__/integration/test-utils.d.ts.map +0 -1
- package/dist/__tests__/integration/test-utils.js +0 -82
- package/dist/__tests__/integration/test-utils.js.map +0 -1
- package/dist/__tests__/integration/tunnel.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/tunnel.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/tunnel.integration.test.js +0 -486
- package/dist/__tests__/integration/tunnel.integration.test.js.map +0 -1
- package/dist/__tests__/integration/variable.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/variable.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/variable.integration.test.js +0 -258
- package/dist/__tests__/integration/variable.integration.test.js.map +0 -1
- package/dist/__tests__/integration/whoami.integration.test.d.ts +0 -2
- package/dist/__tests__/integration/whoami.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/whoami.integration.test.js +0 -116
- package/dist/__tests__/integration/whoami.integration.test.js.map +0 -1
- package/dist/__tests__/outdated.test.d.ts +0 -2
- package/dist/__tests__/outdated.test.d.ts.map +0 -1
- package/dist/__tests__/outdated.test.js +0 -67
- package/dist/__tests__/outdated.test.js.map +0 -1
- package/dist/__tests__/populate.test.d.ts +0 -2
- package/dist/__tests__/populate.test.d.ts.map +0 -1
- package/dist/__tests__/populate.test.js +0 -445
- package/dist/__tests__/populate.test.js.map +0 -1
- package/dist/__tests__/tsconfig-upgrader.test.d.ts +0 -2
- package/dist/__tests__/tsconfig-upgrader.test.d.ts.map +0 -1
- package/dist/__tests__/tsconfig-upgrader.test.js +0 -31
- package/dist/__tests__/tsconfig-upgrader.test.js.map +0 -1
- package/dist/ca-certificate/validation.test.d.ts +0 -2
- package/dist/ca-certificate/validation.test.d.ts.map +0 -1
- package/dist/ca-certificate/validation.test.js +0 -131
- package/dist/ca-certificate/validation.test.js.map +0 -1
- package/dist/common/analytics/cli-invocation.test.d.ts +0 -2
- package/dist/common/analytics/cli-invocation.test.d.ts.map +0 -1
- package/dist/common/analytics/cli-invocation.test.js +0 -51
- package/dist/common/analytics/cli-invocation.test.js.map +0 -1
- package/dist/common/analytics/package-manager.test.d.ts +0 -2
- package/dist/common/analytics/package-manager.test.d.ts.map +0 -1
- package/dist/common/analytics/package-manager.test.js +0 -163
- package/dist/common/analytics/package-manager.test.js.map +0 -1
- package/dist/common/cli-dispatcher.test.d.ts +0 -2
- package/dist/common/cli-dispatcher.test.d.ts.map +0 -1
- package/dist/common/cli-dispatcher.test.js +0 -80
- package/dist/common/cli-dispatcher.test.js.map +0 -1
- package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts +0 -2
- package/dist/common/middleware/check-pnpm-lifecycle.test.d.ts.map +0 -1
- package/dist/common/middleware/check-pnpm-lifecycle.test.js +0 -125
- package/dist/common/middleware/check-pnpm-lifecycle.test.js.map +0 -1
- package/dist/common/middleware/get-environment-param.test.d.ts +0 -2
- package/dist/common/middleware/get-environment-param.test.d.ts.map +0 -1
- package/dist/common/middleware/get-environment-param.test.js +0 -57
- package/dist/common/middleware/get-environment-param.test.js.map +0 -1
- package/dist/common/read-linked-config.test.d.ts +0 -2
- package/dist/common/read-linked-config.test.d.ts.map +0 -1
- package/dist/common/read-linked-config.test.js +0 -363
- package/dist/common/read-linked-config.test.js.map +0 -1
- package/dist/common/terminal.test.d.ts +0 -2
- package/dist/common/terminal.test.d.ts.map +0 -1
- package/dist/common/terminal.test.js +0 -101
- package/dist/common/terminal.test.js.map +0 -1
- package/dist/common/utils/build-environment-prompt-choices.test.d.ts +0 -2
- package/dist/common/utils/build-environment-prompt-choices.test.d.ts.map +0 -1
- package/dist/common/utils/build-environment-prompt-choices.test.js +0 -97
- package/dist/common/utils/build-environment-prompt-choices.test.js.map +0 -1
- package/dist/common/utils/format-environment-type.test.d.ts +0 -2
- package/dist/common/utils/format-environment-type.test.d.ts.map +0 -1
- package/dist/common/utils/format-environment-type.test.js +0 -32
- package/dist/common/utils/format-environment-type.test.js.map +0 -1
- package/dist/common/utils/pnpm-lifecycle.test.d.ts +0 -2
- package/dist/common/utils/pnpm-lifecycle.test.d.ts.map +0 -1
- package/dist/common/utils/pnpm-lifecycle.test.js +0 -196
- package/dist/common/utils/pnpm-lifecycle.test.js.map +0 -1
- package/dist/common/utils/pretty-print-environment-prompt.test.d.ts +0 -2
- package/dist/common/utils/pretty-print-environment-prompt.test.d.ts.map +0 -1
- package/dist/common/utils/pretty-print-environment-prompt.test.js +0 -42
- package/dist/common/utils/pretty-print-environment-prompt.test.js.map +0 -1
- package/dist/common/utils/sort-environments-for-prompt.test.d.ts +0 -2
- package/dist/common/utils/sort-environments-for-prompt.test.d.ts.map +0 -1
- package/dist/common/utils/sort-environments-for-prompt.test.js +0 -82
- package/dist/common/utils/sort-environments-for-prompt.test.js.map +0 -1
- package/dist/common/utils/stringify-config.test.d.ts +0 -2
- package/dist/common/utils/stringify-config.test.d.ts.map +0 -1
- package/dist/common/utils/stringify-config.test.js +0 -80
- package/dist/common/utils/stringify-config.test.js.map +0 -1
- package/dist/common/validators/argument-validators.spec.d.ts +0 -2
- package/dist/common/validators/argument-validators.spec.d.ts.map +0 -1
- package/dist/common/validators/argument-validators.spec.js +0 -181
- package/dist/common/validators/argument-validators.spec.js.map +0 -1
- package/dist/common/worker-output.test.d.ts +0 -2
- package/dist/common/worker-output.test.d.ts.map +0 -1
- package/dist/common/worker-output.test.js +0 -32
- package/dist/common/worker-output.test.js.map +0 -1
- package/dist/deploy/archive.local-registry.test.d.ts +0 -2
- package/dist/deploy/archive.local-registry.test.d.ts.map +0 -1
- package/dist/deploy/archive.local-registry.test.js +0 -100
- package/dist/deploy/archive.local-registry.test.js.map +0 -1
- package/dist/deploy/archive.test.d.ts +0 -2
- package/dist/deploy/archive.test.d.ts.map +0 -1
- package/dist/deploy/archive.test.js +0 -248
- package/dist/deploy/archive.test.js.map +0 -1
- package/dist/deploy/classify-build-probe.test.d.ts +0 -2
- package/dist/deploy/classify-build-probe.test.d.ts.map +0 -1
- package/dist/deploy/classify-build-probe.test.js +0 -51
- package/dist/deploy/classify-build-probe.test.js.map +0 -1
- package/dist/deploy/poll-deployment.test.d.ts +0 -2
- package/dist/deploy/poll-deployment.test.d.ts.map +0 -1
- package/dist/deploy/poll-deployment.test.js +0 -158
- package/dist/deploy/poll-deployment.test.js.map +0 -1
- package/dist/dev/zuplo-local-gitignore.test.d.ts +0 -2
- package/dist/dev/zuplo-local-gitignore.test.d.ts.map +0 -1
- package/dist/dev/zuplo-local-gitignore.test.js +0 -58
- package/dist/dev/zuplo-local-gitignore.test.js.map +0 -1
- package/dist/editor/e2e/editor.spec.d.ts +0 -2
- package/dist/editor/e2e/editor.spec.d.ts.map +0 -1
- package/dist/editor/e2e/editor.spec.js +0 -44
- package/dist/editor/e2e/editor.spec.js.map +0 -1
- package/dist/link/project-type.test.d.ts +0 -2
- package/dist/link/project-type.test.d.ts.map +0 -1
- package/dist/link/project-type.test.js +0 -225
- package/dist/link/project-type.test.js.map +0 -1
- package/dist/lint/resolve-binary.test.d.ts +0 -2
- package/dist/lint/resolve-binary.test.d.ts.map +0 -1
- package/dist/lint/resolve-binary.test.js +0 -155
- package/dist/lint/resolve-binary.test.js.map +0 -1
- package/dist/open-api/convert/handler.spec.d.ts +0 -2
- package/dist/open-api/convert/handler.spec.d.ts.map +0 -1
- package/dist/open-api/convert/handler.spec.js +0 -301
- package/dist/open-api/convert/handler.spec.js.map +0 -1
- package/dist/open-api/merge/handler.spec.d.ts +0 -2
- package/dist/open-api/merge/handler.spec.d.ts.map +0 -1
- package/dist/open-api/merge/handler.spec.js +0 -673
- package/dist/open-api/merge/handler.spec.js.map +0 -1
- package/dist/open-api/overlay/handler.spec.d.ts +0 -2
- package/dist/open-api/overlay/handler.spec.d.ts.map +0 -1
- package/dist/open-api/overlay/handler.spec.js +0 -346
- package/dist/open-api/overlay/handler.spec.js.map +0 -1
- package/dist/source/ai-gateway/files.test.d.ts +0 -2
- package/dist/source/ai-gateway/files.test.d.ts.map +0 -1
- package/dist/source/ai-gateway/files.test.js +0 -135
- package/dist/source/ai-gateway/files.test.js.map +0 -1
- package/dist/source/ai-gateway/handler.test.d.ts +0 -2
- package/dist/source/ai-gateway/handler.test.d.ts.map +0 -1
- package/dist/source/ai-gateway/handler.test.js +0 -113
- package/dist/source/ai-gateway/handler.test.js.map +0 -1
- package/dist/source/ai-gateway/package.test.d.ts +0 -2
- package/dist/source/ai-gateway/package.test.d.ts.map +0 -1
- package/dist/source/ai-gateway/package.test.js +0 -30
- package/dist/source/ai-gateway/package.test.js.map +0 -1
- package/dist/source/ai-gateway/planner.test.d.ts +0 -2
- package/dist/source/ai-gateway/planner.test.d.ts.map +0 -1
- package/dist/source/ai-gateway/planner.test.js +0 -330
- package/dist/source/ai-gateway/planner.test.js.map +0 -1
- package/dist/source/ai-gateway/release.test.d.ts +0 -2
- package/dist/source/ai-gateway/release.test.d.ts.map +0 -1
- package/dist/source/ai-gateway/release.test.js +0 -62
- package/dist/source/ai-gateway/release.test.js.map +0 -1
- package/dist/test/invoke-test.test.d.ts +0 -2
- package/dist/test/invoke-test.test.d.ts.map +0 -1
- package/dist/test/invoke-test.test.js +0 -150
- package/dist/test/invoke-test.test.js.map +0 -1
- package/dist/test/test-files.test.d.ts +0 -2
- package/dist/test/test-files.test.d.ts.map +0 -1
- package/dist/test/test-files.test.js +0 -57
- package/dist/test/test-files.test.js.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts +0 -2
- package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.d.ts.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js +0 -289
- package/node_modules/@zuplo/openapi-tools/dist/file-format.spec.js.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts +0 -2
- package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.d.ts.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js +0 -181
- package/node_modules/@zuplo/openapi-tools/dist/merge-fixtures.spec.js.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts +0 -2
- package/node_modules/@zuplo/openapi-tools/dist/merge.spec.d.ts.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js +0 -399
- package/node_modules/@zuplo/openapi-tools/dist/merge.spec.js.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts +0 -2
- package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.d.ts.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js +0 -779
- package/node_modules/@zuplo/openapi-tools/dist/overlay.spec.js.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts +0 -2
- package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.d.ts.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js +0 -269
- package/node_modules/@zuplo/openapi-tools/dist/path-transform.spec.js.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts +0 -2
- package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.d.ts.map +0 -1
- package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js +0 -93
- package/node_modules/@zuplo/openapi-tools/dist/url-utils.spec.js.map +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-6YPRGG62.js.map +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js +0 -37
- package/node_modules/@zuplo/runtime/out/esm/chunk-PBDT4FDO.js.map +0 -1
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ2BHVUH.js.map → chunk-CDEAY3VY.js.map} +0 -0
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-PBDT4FDO.js.LEGAL.txt → chunk-LVSZ3WTO.js.LEGAL.txt} +0 -0
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-VTO3F6DK.js.map → chunk-NUVXDVLJ.js.map} +0 -0
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-6YPRGG62.js.LEGAL.txt → chunk-TPYCFLC7.js.LEGAL.txt} +0 -0
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, it } from "node:test";
|
|
2
|
-
import { assert } from "chai";
|
|
3
|
-
import { getGlobalDispatcher, MockAgent, setGlobalDispatcher, } from "undici";
|
|
4
|
-
import { pollDeployment } from "./poll-deployment.js";
|
|
5
|
-
const DEV_API_ORIGIN = "https://developer.test";
|
|
6
|
-
const DEPLOYMENT_ORIGIN = "https://my-api.zuplo.app";
|
|
7
|
-
const PRIVATE_DEPLOYMENT_ORIGIN = "https://gateway.example.com";
|
|
8
|
-
const STATUS_PATH = "/v1/accounts/test-account/projects/test-project/deployment-status/deployment-123";
|
|
9
|
-
const BUILD_PATH = "/__zuplo/build";
|
|
10
|
-
const BUILD_ID = "build-new";
|
|
11
|
-
const LOG_URL = "https://portal.zuplo.com/builds/build-new";
|
|
12
|
-
const INIT_ERROR_DETAIL = "Value of 'allowedOrigins' on custom cors policies is invalid.";
|
|
13
|
-
const FALLBACK_INIT_ERROR_DETAIL = "The gateway failed to initialize after deployment. Check the deployment logs for details.";
|
|
14
|
-
const ENVIRONMENT_VARIABLES = [
|
|
15
|
-
"ZUPLO_DEVELOPER_API_ENDPOINT",
|
|
16
|
-
"MAX_POLL_RETRIES",
|
|
17
|
-
"POLL_INTERVAL",
|
|
18
|
-
"DEPLOY_INIT_ERROR_FAIL_FAST",
|
|
19
|
-
];
|
|
20
|
-
const argv = { authToken: "tok" };
|
|
21
|
-
function statusBody(overrides = {}) {
|
|
22
|
-
return {
|
|
23
|
-
status: "SUCCESS",
|
|
24
|
-
url: DEPLOYMENT_ORIGIN,
|
|
25
|
-
logUrl: LOG_URL,
|
|
26
|
-
buildId: BUILD_ID,
|
|
27
|
-
...overrides,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function initErrorBody(overrides = {}) {
|
|
31
|
-
return {
|
|
32
|
-
status: 500,
|
|
33
|
-
title: "Gateway Initialization Error",
|
|
34
|
-
type: "https://httpproblems.com/http-status/500",
|
|
35
|
-
detail: INIT_ERROR_DETAIL,
|
|
36
|
-
trace: { timestamp: 0, buildId: BUILD_ID },
|
|
37
|
-
...overrides,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
describe("pollDeployment", () => {
|
|
41
|
-
let mockAgent;
|
|
42
|
-
let previousDispatcher;
|
|
43
|
-
let devApiPool;
|
|
44
|
-
let deploymentPool;
|
|
45
|
-
let previousEnvironment;
|
|
46
|
-
let spinner;
|
|
47
|
-
beforeEach(() => {
|
|
48
|
-
previousEnvironment = Object.fromEntries(ENVIRONMENT_VARIABLES.map((name) => [name, process.env[name]]));
|
|
49
|
-
process.env.ZUPLO_DEVELOPER_API_ENDPOINT = DEV_API_ORIGIN;
|
|
50
|
-
process.env.MAX_POLL_RETRIES = "3";
|
|
51
|
-
process.env.POLL_INTERVAL = "1";
|
|
52
|
-
delete process.env.DEPLOY_INIT_ERROR_FAIL_FAST;
|
|
53
|
-
previousDispatcher = getGlobalDispatcher();
|
|
54
|
-
mockAgent = new MockAgent();
|
|
55
|
-
mockAgent.disableNetConnect();
|
|
56
|
-
setGlobalDispatcher(mockAgent);
|
|
57
|
-
devApiPool = mockAgent.get(DEV_API_ORIGIN);
|
|
58
|
-
deploymentPool = mockAgent.get(DEPLOYMENT_ORIGIN);
|
|
59
|
-
spinner = { suffixText: "" };
|
|
60
|
-
});
|
|
61
|
-
afterEach(async () => {
|
|
62
|
-
await mockAgent.close();
|
|
63
|
-
setGlobalDispatcher(previousDispatcher);
|
|
64
|
-
for (const name of ENVIRONMENT_VARIABLES) {
|
|
65
|
-
const value = previousEnvironment[name];
|
|
66
|
-
if (value === undefined) {
|
|
67
|
-
delete process.env[name];
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
process.env[name] = value;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
function interceptStatus(body, times = 1) {
|
|
75
|
-
devApiPool
|
|
76
|
-
.intercept({ path: STATUS_PATH, method: "GET" })
|
|
77
|
-
.reply(200, body)
|
|
78
|
-
.times(times);
|
|
79
|
-
}
|
|
80
|
-
function interceptProbe(status, body, times = 1) {
|
|
81
|
-
deploymentPool
|
|
82
|
-
.intercept({ path: BUILD_PATH, method: "GET" })
|
|
83
|
-
.reply(status, body)
|
|
84
|
-
.times(times);
|
|
85
|
-
}
|
|
86
|
-
function poll() {
|
|
87
|
-
return pollDeployment(argv, "deployment-123", "test-account", "test-project", spinner);
|
|
88
|
-
}
|
|
89
|
-
it("fails fast after two consecutive matching initialization errors", async () => {
|
|
90
|
-
interceptStatus(statusBody(), 2);
|
|
91
|
-
interceptProbe(500, initErrorBody(), 2);
|
|
92
|
-
const result = await poll();
|
|
93
|
-
assert.deepEqual(result, {
|
|
94
|
-
logUrl: LOG_URL,
|
|
95
|
-
initError: { detail: INIT_ERROR_DETAIL },
|
|
96
|
-
});
|
|
97
|
-
assert.strictEqual(mockAgent.pendingInterceptors().length, 0);
|
|
98
|
-
});
|
|
99
|
-
it("succeeds when one matching initialization error is followed by a live probe", async () => {
|
|
100
|
-
interceptStatus(statusBody(), 2);
|
|
101
|
-
interceptProbe(500, initErrorBody());
|
|
102
|
-
interceptProbe(200, { buildId: BUILD_ID });
|
|
103
|
-
assert.deepEqual(await poll(), {
|
|
104
|
-
url: DEPLOYMENT_ORIGIN,
|
|
105
|
-
logUrl: LOG_URL,
|
|
106
|
-
});
|
|
107
|
-
assert.strictEqual(mockAgent.pendingInterceptors().length, 0);
|
|
108
|
-
});
|
|
109
|
-
it("polls to exhaustion when the initialization error is for another build", async () => {
|
|
110
|
-
interceptStatus(statusBody(), 3);
|
|
111
|
-
interceptProbe(500, initErrorBody({ trace: { timestamp: 0, buildId: "build-old" } }), 3);
|
|
112
|
-
assert.deepEqual(await poll(), { logUrl: LOG_URL });
|
|
113
|
-
});
|
|
114
|
-
it("does not fail fast when the status response omits buildId", async () => {
|
|
115
|
-
interceptStatus(statusBody({ buildId: undefined }), 3);
|
|
116
|
-
interceptProbe(500, initErrorBody(), 3);
|
|
117
|
-
assert.deepEqual(await poll(), { logUrl: LOG_URL });
|
|
118
|
-
});
|
|
119
|
-
it("keeps polling after a non-JSON 5xx probe response", async () => {
|
|
120
|
-
interceptStatus(statusBody(), 3);
|
|
121
|
-
interceptProbe(500, "<html>unavailable</html>", 3);
|
|
122
|
-
assert.deepEqual(await poll(), { logUrl: LOG_URL });
|
|
123
|
-
});
|
|
124
|
-
it("uses the fallback detail when a matching initialization error omits detail", async () => {
|
|
125
|
-
interceptStatus(statusBody(), 2);
|
|
126
|
-
interceptProbe(500, initErrorBody({ detail: undefined }), 2);
|
|
127
|
-
assert.deepEqual(await poll(), {
|
|
128
|
-
logUrl: LOG_URL,
|
|
129
|
-
initError: { detail: FALLBACK_INIT_ERROR_DETAIL },
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
it("returns the latest build log URL when in-progress polling is exhausted", async () => {
|
|
133
|
-
interceptStatus(statusBody({ status: "IN_PROGRESS", url: undefined }), 3);
|
|
134
|
-
assert.deepEqual(await poll(), { logUrl: LOG_URL });
|
|
135
|
-
});
|
|
136
|
-
it("returns the deployment URL after a successful build probe", async () => {
|
|
137
|
-
interceptStatus(statusBody());
|
|
138
|
-
interceptProbe(200, { buildId: BUILD_ID });
|
|
139
|
-
assert.deepEqual(await poll(), {
|
|
140
|
-
url: DEPLOYMENT_ORIGIN,
|
|
141
|
-
logUrl: LOG_URL,
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
it("returns a non-Zuplo deployment URL without probing it", async () => {
|
|
145
|
-
interceptStatus(statusBody({ url: PRIVATE_DEPLOYMENT_ORIGIN }));
|
|
146
|
-
assert.deepEqual(await poll(), {
|
|
147
|
-
url: PRIVATE_DEPLOYMENT_ORIGIN,
|
|
148
|
-
logUrl: LOG_URL,
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
it("keeps polling matching initialization errors when fail-fast is disabled", async () => {
|
|
152
|
-
process.env.DEPLOY_INIT_ERROR_FAIL_FAST = "false";
|
|
153
|
-
interceptStatus(statusBody(), 3);
|
|
154
|
-
interceptProbe(500, initErrorBody(), 3);
|
|
155
|
-
assert.deepEqual(await poll(), { logUrl: LOG_URL });
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
//# sourceMappingURL=poll-deployment.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"poll-deployment.test.js","sourceRoot":"","sources":["../../src/deploy/poll-deployment.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, it } from \"node:test\";\nimport { assert } from \"chai\";\nimport type { Ora } from \"ora\";\nimport {\n type Dispatcher,\n getGlobalDispatcher,\n MockAgent,\n type MockPool,\n setGlobalDispatcher,\n} from \"undici\";\nimport type { Arguments } from \"./handler.js\";\nimport { pollDeployment } from \"./poll-deployment.js\";\n\nconst DEV_API_ORIGIN = \"https://developer.test\";\nconst DEPLOYMENT_ORIGIN = \"https://my-api.zuplo.app\";\nconst PRIVATE_DEPLOYMENT_ORIGIN = \"https://gateway.example.com\";\nconst STATUS_PATH =\n \"/v1/accounts/test-account/projects/test-project/deployment-status/deployment-123\";\nconst BUILD_PATH = \"/__zuplo/build\";\nconst BUILD_ID = \"build-new\";\nconst LOG_URL = \"https://portal.zuplo.com/builds/build-new\";\nconst INIT_ERROR_DETAIL =\n \"Value of 'allowedOrigins' on custom cors policies is invalid.\";\nconst FALLBACK_INIT_ERROR_DETAIL =\n \"The gateway failed to initialize after deployment. Check the deployment logs for details.\";\nconst ENVIRONMENT_VARIABLES = [\n \"ZUPLO_DEVELOPER_API_ENDPOINT\",\n \"MAX_POLL_RETRIES\",\n \"POLL_INTERVAL\",\n \"DEPLOY_INIT_ERROR_FAIL_FAST\",\n] as const;\n\nconst argv = { authToken: \"tok\" } as Arguments;\n\nfunction statusBody(overrides: Record<string, unknown> = {}) {\n return {\n status: \"SUCCESS\",\n url: DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n buildId: BUILD_ID,\n ...overrides,\n };\n}\n\nfunction initErrorBody(overrides: Record<string, unknown> = {}) {\n return {\n status: 500,\n title: \"Gateway Initialization Error\",\n type: \"https://httpproblems.com/http-status/500\",\n detail: INIT_ERROR_DETAIL,\n trace: { timestamp: 0, buildId: BUILD_ID },\n ...overrides,\n };\n}\n\ndescribe(\"pollDeployment\", () => {\n let mockAgent: MockAgent;\n let previousDispatcher: Dispatcher;\n let devApiPool: MockPool;\n let deploymentPool: MockPool;\n let previousEnvironment: Record<string, string | undefined>;\n let spinner: Ora;\n\n beforeEach(() => {\n previousEnvironment = Object.fromEntries(\n ENVIRONMENT_VARIABLES.map((name) => [name, process.env[name]])\n );\n process.env.ZUPLO_DEVELOPER_API_ENDPOINT = DEV_API_ORIGIN;\n process.env.MAX_POLL_RETRIES = \"3\";\n process.env.POLL_INTERVAL = \"1\";\n delete process.env.DEPLOY_INIT_ERROR_FAIL_FAST;\n\n previousDispatcher = getGlobalDispatcher();\n mockAgent = new MockAgent();\n mockAgent.disableNetConnect();\n setGlobalDispatcher(mockAgent);\n devApiPool = mockAgent.get(DEV_API_ORIGIN);\n deploymentPool = mockAgent.get(DEPLOYMENT_ORIGIN);\n spinner = { suffixText: \"\" } as unknown as Ora;\n });\n\n afterEach(async () => {\n await mockAgent.close();\n setGlobalDispatcher(previousDispatcher);\n\n for (const name of ENVIRONMENT_VARIABLES) {\n const value = previousEnvironment[name];\n if (value === undefined) {\n delete process.env[name];\n } else {\n process.env[name] = value;\n }\n }\n });\n\n function interceptStatus(body: Record<string, unknown>, times = 1) {\n devApiPool\n .intercept({ path: STATUS_PATH, method: \"GET\" })\n .reply(200, body)\n .times(times);\n }\n\n function interceptProbe(\n status: number,\n body: Record<string, unknown> | string,\n times = 1\n ) {\n deploymentPool\n .intercept({ path: BUILD_PATH, method: \"GET\" })\n .reply(status, body)\n .times(times);\n }\n\n function poll() {\n return pollDeployment(\n argv,\n \"deployment-123\",\n \"test-account\",\n \"test-project\",\n spinner\n );\n }\n\n it(\"fails fast after two consecutive matching initialization errors\", async () => {\n interceptStatus(statusBody(), 2);\n interceptProbe(500, initErrorBody(), 2);\n\n const result = await poll();\n\n assert.deepEqual(result, {\n logUrl: LOG_URL,\n initError: { detail: INIT_ERROR_DETAIL },\n });\n assert.strictEqual(mockAgent.pendingInterceptors().length, 0);\n });\n\n it(\"succeeds when one matching initialization error is followed by a live probe\", async () => {\n interceptStatus(statusBody(), 2);\n interceptProbe(500, initErrorBody());\n interceptProbe(200, { buildId: BUILD_ID });\n\n assert.deepEqual(await poll(), {\n url: DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n });\n assert.strictEqual(mockAgent.pendingInterceptors().length, 0);\n });\n\n it(\"polls to exhaustion when the initialization error is for another build\", async () => {\n interceptStatus(statusBody(), 3);\n interceptProbe(\n 500,\n initErrorBody({ trace: { timestamp: 0, buildId: \"build-old\" } }),\n 3\n );\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"does not fail fast when the status response omits buildId\", async () => {\n interceptStatus(statusBody({ buildId: undefined }), 3);\n interceptProbe(500, initErrorBody(), 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"keeps polling after a non-JSON 5xx probe response\", async () => {\n interceptStatus(statusBody(), 3);\n interceptProbe(500, \"<html>unavailable</html>\", 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"uses the fallback detail when a matching initialization error omits detail\", async () => {\n interceptStatus(statusBody(), 2);\n interceptProbe(500, initErrorBody({ detail: undefined }), 2);\n\n assert.deepEqual(await poll(), {\n logUrl: LOG_URL,\n initError: { detail: FALLBACK_INIT_ERROR_DETAIL },\n });\n });\n\n it(\"returns the latest build log URL when in-progress polling is exhausted\", async () => {\n interceptStatus(statusBody({ status: \"IN_PROGRESS\", url: undefined }), 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"returns the deployment URL after a successful build probe\", async () => {\n interceptStatus(statusBody());\n interceptProbe(200, { buildId: BUILD_ID });\n\n assert.deepEqual(await poll(), {\n url: DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n });\n });\n\n it(\"returns a non-Zuplo deployment URL without probing it\", async () => {\n interceptStatus(statusBody({ url: PRIVATE_DEPLOYMENT_ORIGIN }));\n\n assert.deepEqual(await poll(), {\n url: PRIVATE_DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n });\n });\n\n it(\"keeps polling matching initialization errors when fail-fast is disabled\", async () => {\n process.env.DEPLOY_INIT_ERROR_FAIL_FAST = \"false\";\n interceptStatus(statusBody(), 3);\n interceptProbe(500, initErrorBody(), 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"zuplo-local-gitignore.test.d.ts","sourceRoot":"","sources":["../../src/dev/zuplo-local-gitignore.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { afterEach, beforeEach, describe, it } from "node:test";
|
|
6
|
-
import { shouldWarnAboutZuploLocalGitignore } from "./zuplo-local-gitignore.js";
|
|
7
|
-
describe("shouldWarnAboutZuploLocalGitignore", () => {
|
|
8
|
-
let sourceDirectory;
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
sourceDirectory = mkdtempSync(join(tmpdir(), "zuplo-local-gitignore-"));
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
rmSync(sourceDirectory, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
it("returns false when .zuplo-local does not exist", () => {
|
|
16
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), false);
|
|
17
|
-
});
|
|
18
|
-
it("returns true when .zuplo-local exists and there is no .gitignore", () => {
|
|
19
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
20
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), true);
|
|
21
|
-
});
|
|
22
|
-
it("returns true when .gitignore does not cover .zuplo-local", () => {
|
|
23
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
24
|
-
writeFileSync(join(sourceDirectory, ".gitignore"), "node_modules\ndist\n.env\n");
|
|
25
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), true);
|
|
26
|
-
});
|
|
27
|
-
it("returns false when .gitignore contains '.zuplo-local'", () => {
|
|
28
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
29
|
-
writeFileSync(join(sourceDirectory, ".gitignore"), "node_modules\n.zuplo-local\n");
|
|
30
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), false);
|
|
31
|
-
});
|
|
32
|
-
it("returns false when .gitignore contains '.zuplo-local/'", () => {
|
|
33
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
34
|
-
writeFileSync(join(sourceDirectory, ".gitignore"), "node_modules\n.zuplo-local/\n");
|
|
35
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), false);
|
|
36
|
-
});
|
|
37
|
-
it("returns false when .gitignore contains root-anchored '/.zuplo-local/'", () => {
|
|
38
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
39
|
-
writeFileSync(join(sourceDirectory, ".gitignore"), "node_modules\n/.zuplo-local/\n");
|
|
40
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), false);
|
|
41
|
-
});
|
|
42
|
-
it("returns false when .gitignore contains root-anchored '/.zuplo-local'", () => {
|
|
43
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
44
|
-
writeFileSync(join(sourceDirectory, ".gitignore"), "node_modules\n/.zuplo-local\n");
|
|
45
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), false);
|
|
46
|
-
});
|
|
47
|
-
it("trims whitespace around .gitignore lines", () => {
|
|
48
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
49
|
-
writeFileSync(join(sourceDirectory, ".gitignore"), " .zuplo-local/ \n");
|
|
50
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), false);
|
|
51
|
-
});
|
|
52
|
-
it("does not match unrelated lines that merely contain the name", () => {
|
|
53
|
-
mkdirSync(join(sourceDirectory, ".zuplo-local"));
|
|
54
|
-
writeFileSync(join(sourceDirectory, ".gitignore"), "# .zuplo-local is great\nfoo/.zuplo-local\n");
|
|
55
|
-
assert.strictEqual(shouldWarnAboutZuploLocalGitignore(sourceDirectory), true);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
//# sourceMappingURL=zuplo-local-gitignore.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"zuplo-local-gitignore.test.js","sourceRoot":"","sources":["../../src/dev/zuplo-local-gitignore.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert\";\nimport { mkdirSync, mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { afterEach, beforeEach, describe, it } from \"node:test\";\nimport { shouldWarnAboutZuploLocalGitignore } from \"./zuplo-local-gitignore.js\";\n\ndescribe(\"shouldWarnAboutZuploLocalGitignore\", () => {\n let sourceDirectory: string;\n\n beforeEach(() => {\n sourceDirectory = mkdtempSync(join(tmpdir(), \"zuplo-local-gitignore-\"));\n });\n\n afterEach(() => {\n rmSync(sourceDirectory, { recursive: true, force: true });\n });\n\n it(\"returns false when .zuplo-local does not exist\", () => {\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n false\n );\n });\n\n it(\"returns true when .zuplo-local exists and there is no .gitignore\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n true\n );\n });\n\n it(\"returns true when .gitignore does not cover .zuplo-local\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n writeFileSync(\n join(sourceDirectory, \".gitignore\"),\n \"node_modules\\ndist\\n.env\\n\"\n );\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n true\n );\n });\n\n it(\"returns false when .gitignore contains '.zuplo-local'\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n writeFileSync(\n join(sourceDirectory, \".gitignore\"),\n \"node_modules\\n.zuplo-local\\n\"\n );\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n false\n );\n });\n\n it(\"returns false when .gitignore contains '.zuplo-local/'\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n writeFileSync(\n join(sourceDirectory, \".gitignore\"),\n \"node_modules\\n.zuplo-local/\\n\"\n );\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n false\n );\n });\n\n it(\"returns false when .gitignore contains root-anchored '/.zuplo-local/'\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n writeFileSync(\n join(sourceDirectory, \".gitignore\"),\n \"node_modules\\n/.zuplo-local/\\n\"\n );\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n false\n );\n });\n\n it(\"returns false when .gitignore contains root-anchored '/.zuplo-local'\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n writeFileSync(\n join(sourceDirectory, \".gitignore\"),\n \"node_modules\\n/.zuplo-local\\n\"\n );\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n false\n );\n });\n\n it(\"trims whitespace around .gitignore lines\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n writeFileSync(join(sourceDirectory, \".gitignore\"), \" .zuplo-local/ \\n\");\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n false\n );\n });\n\n it(\"does not match unrelated lines that merely contain the name\", () => {\n mkdirSync(join(sourceDirectory, \".zuplo-local\"));\n writeFileSync(\n join(sourceDirectory, \".gitignore\"),\n \"# .zuplo-local is great\\nfoo/.zuplo-local\\n\"\n );\n assert.strictEqual(\n shouldWarnAboutZuploLocalGitignore(sourceDirectory),\n true\n );\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.spec.d.ts","sourceRoot":"","sources":["../../../src/editor/e2e/editor.spec.ts"],"names":[],"mappings":""}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "@playwright/test";
|
|
2
|
-
const EDITOR_URL = `http://localhost:${process.env.EDITOR_PORT}`;
|
|
3
|
-
const GATEWAY_URL = `http://localhost:${process.env.GATEWAY_PORT}`;
|
|
4
|
-
test.describe("Editor UI Tests", () => {
|
|
5
|
-
test.beforeEach(async ({ page }) => {
|
|
6
|
-
await page.goto(EDITOR_URL);
|
|
7
|
-
});
|
|
8
|
-
test("Project view displays gateway and splash content", async ({ page }) => {
|
|
9
|
-
const projectHeader = page.getByRole("link", { name: "Project" });
|
|
10
|
-
await expect(projectHeader).toBeVisible();
|
|
11
|
-
await projectHeader.click();
|
|
12
|
-
await expect(page).toHaveURL(/\/dev\/project\/local$/);
|
|
13
|
-
await expect(page.getByRole("heading", { name: "Welcome to your Gateway" })).toBeVisible();
|
|
14
|
-
await expect(page.getByText("Gateway").first()).toBeVisible();
|
|
15
|
-
await expect(page.getByRole("link", { name: GATEWAY_URL })).toBeVisible();
|
|
16
|
-
await expect(page.getByText("Developer Portal")).toBeVisible();
|
|
17
|
-
await expect(page.getByRole("button", { name: "Open Portal" })).toBeVisible();
|
|
18
|
-
await expect(page.getByRole("link", { name: "Start Building" })).toBeVisible();
|
|
19
|
-
await expect(page.getByRole("link", { name: "Quickstart" })).toBeVisible();
|
|
20
|
-
await expect(page.getByRole("heading", { name: "Support" })).toBeVisible();
|
|
21
|
-
});
|
|
22
|
-
test("Code view displays routes and route designer", async ({ page }) => {
|
|
23
|
-
test.setTimeout(60_000);
|
|
24
|
-
const codeHeader = page.getByRole("link", { name: "Code" });
|
|
25
|
-
await expect(codeHeader).toBeVisible();
|
|
26
|
-
await codeHeader.click();
|
|
27
|
-
await expect(page).toHaveURL(/\/dev\/project\/local\/edit/);
|
|
28
|
-
await expect(page.getByTestId("add-route-btn").first()).toBeVisible({
|
|
29
|
-
timeout: 30_000,
|
|
30
|
-
});
|
|
31
|
-
const expandFileTree = page.getByTestId("expand-file-tree");
|
|
32
|
-
if (await expandFileTree.isVisible()) {
|
|
33
|
-
await expandFileTree.click();
|
|
34
|
-
}
|
|
35
|
-
const routesFile = page.getByTestId("repros.oas.json");
|
|
36
|
-
await expect(routesFile).toBeVisible();
|
|
37
|
-
await routesFile.click();
|
|
38
|
-
await expect(page).toHaveURL(/path=%2Fconfig%2Frepros\.oas\.json/);
|
|
39
|
-
await expect(page.getByRole("tab", { name: "Route Designer" })).toBeVisible();
|
|
40
|
-
await expect(page.getByRole("tab", { name: "repros.oas.json" })).toBeVisible();
|
|
41
|
-
await expect(page.getByText("Create an Unsigned Transaction")).toBeVisible();
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
//# sourceMappingURL=editor.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.spec.js","sourceRoot":"","sources":["../../../src/editor/e2e/editor.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, test } from \"@playwright/test\";\n\nconst EDITOR_URL = `http://localhost:${process.env.EDITOR_PORT}`;\nconst GATEWAY_URL = `http://localhost:${process.env.GATEWAY_PORT}`;\n\ntest.describe(\"Editor UI Tests\", () => {\n test.beforeEach(async ({ page }) => {\n await page.goto(EDITOR_URL);\n });\n\n test(\"Project view displays gateway and splash content\", async ({ page }) => {\n const projectHeader = page.getByRole(\"link\", { name: \"Project\" });\n await expect(projectHeader).toBeVisible();\n\n await projectHeader.click();\n\n await expect(page).toHaveURL(/\\/dev\\/project\\/local$/);\n\n await expect(\n page.getByRole(\"heading\", { name: \"Welcome to your Gateway\" })\n ).toBeVisible();\n\n await expect(page.getByText(\"Gateway\").first()).toBeVisible();\n await expect(page.getByRole(\"link\", { name: GATEWAY_URL })).toBeVisible();\n\n await expect(page.getByText(\"Developer Portal\")).toBeVisible();\n await expect(\n page.getByRole(\"button\", { name: \"Open Portal\" })\n ).toBeVisible();\n\n await expect(\n page.getByRole(\"link\", { name: \"Start Building\" })\n ).toBeVisible();\n await expect(page.getByRole(\"link\", { name: \"Quickstart\" })).toBeVisible();\n\n await expect(page.getByRole(\"heading\", { name: \"Support\" })).toBeVisible();\n });\n\n test(\"Code view displays routes and route designer\", async ({ page }) => {\n test.setTimeout(60_000);\n\n const codeHeader = page.getByRole(\"link\", { name: \"Code\" });\n await expect(codeHeader).toBeVisible();\n\n await codeHeader.click();\n\n await expect(page).toHaveURL(/\\/dev\\/project\\/local\\/edit/);\n\n // Code view auto-opens the first *.oas.json; wait for the designer.\n await expect(page.getByTestId(\"add-route-btn\").first()).toBeVisible({\n timeout: 30_000,\n });\n\n // File tree defaults to collapsed. Expand only if needed — prefs can\n // persist across runs when the local editor server is reused.\n const expandFileTree = page.getByTestId(\"expand-file-tree\");\n if (await expandFileTree.isVisible()) {\n await expandFileTree.click();\n }\n\n const routesFile = page.getByTestId(\"repros.oas.json\");\n await expect(routesFile).toBeVisible();\n await routesFile.click();\n\n await expect(page).toHaveURL(/path=%2Fconfig%2Frepros\\.oas\\.json/);\n\n await expect(\n page.getByRole(\"tab\", { name: \"Route Designer\" })\n ).toBeVisible();\n await expect(\n page.getByRole(\"tab\", { name: \"repros.oas.json\" })\n ).toBeVisible();\n\n await expect(\n page.getByText(\"Create an Unsigned Transaction\")\n ).toBeVisible();\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"project-type.test.d.ts","sourceRoot":"","sources":["../../src/link/project-type.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { afterEach, beforeEach, describe, it, mock } from "node:test";
|
|
6
|
-
import { detectProjectType, syncProjectTypeForLink, updateProjectType, } from "./project-type.js";
|
|
7
|
-
describe("link project type detection", () => {
|
|
8
|
-
let testDir;
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
testDir = await mkdtemp(join(tmpdir(), "zuplo-dev-project-type-test-"));
|
|
11
|
-
});
|
|
12
|
-
afterEach(async () => {
|
|
13
|
-
mock.restoreAll();
|
|
14
|
-
await rm(testDir, { recursive: true, force: true });
|
|
15
|
-
});
|
|
16
|
-
it("detects a managed-dedicated project", async () => {
|
|
17
|
-
mock.method(globalThis, "fetch", async () => {
|
|
18
|
-
return Response.json({
|
|
19
|
-
data: [
|
|
20
|
-
{ name: "other-project", type: "managed-edge" },
|
|
21
|
-
{ name: "my-project", type: "managed-dedicated" },
|
|
22
|
-
],
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
const result = await detectProjectType({
|
|
26
|
-
accountName: "my-account",
|
|
27
|
-
authToken: "token",
|
|
28
|
-
projectName: "my-project",
|
|
29
|
-
});
|
|
30
|
-
assert.strictEqual(result, "managed-dedicated");
|
|
31
|
-
});
|
|
32
|
-
it("uses the explicitly designated project when multiple projects exist", async () => {
|
|
33
|
-
mock.method(globalThis, "fetch", async () => {
|
|
34
|
-
return Response.json({
|
|
35
|
-
data: [
|
|
36
|
-
{ name: "linked-project", type: "managed-dedicated" },
|
|
37
|
-
{ name: "explicit-project", type: "managed-edge" },
|
|
38
|
-
],
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
const result = await detectProjectType({
|
|
42
|
-
accountName: "my-account",
|
|
43
|
-
authToken: "token",
|
|
44
|
-
projectName: "explicit-project",
|
|
45
|
-
});
|
|
46
|
-
assert.strictEqual(result, "managed-edge");
|
|
47
|
-
});
|
|
48
|
-
it("defaults self-hosted and unknown project types to managed-edge", async () => {
|
|
49
|
-
mock.method(globalThis, "fetch", async () => {
|
|
50
|
-
return Response.json({
|
|
51
|
-
data: [{ name: "my-project", type: "self-hosted" }],
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
const result = await detectProjectType({
|
|
55
|
-
accountName: "my-account",
|
|
56
|
-
authToken: "token",
|
|
57
|
-
projectName: "my-project",
|
|
58
|
-
});
|
|
59
|
-
assert.strictEqual(result, "managed-edge");
|
|
60
|
-
});
|
|
61
|
-
it("defaults to managed-edge when running offline", async () => {
|
|
62
|
-
mock.method(globalThis, "fetch", async () => {
|
|
63
|
-
throw new Error("offline");
|
|
64
|
-
});
|
|
65
|
-
const result = await detectProjectType({
|
|
66
|
-
accountName: "my-account",
|
|
67
|
-
authToken: "token",
|
|
68
|
-
projectName: "my-project",
|
|
69
|
-
});
|
|
70
|
-
assert.strictEqual(result, "managed-edge");
|
|
71
|
-
});
|
|
72
|
-
it("resolves the account from who-am-i when it is not supplied", async () => {
|
|
73
|
-
const requests = [];
|
|
74
|
-
mock.method(globalThis, "fetch", async (input) => {
|
|
75
|
-
requests.push(String(input));
|
|
76
|
-
if (String(input).endsWith("/v1/who-am-i")) {
|
|
77
|
-
return Response.json({ account: "resolved-account" });
|
|
78
|
-
}
|
|
79
|
-
return Response.json({
|
|
80
|
-
data: [{ name: "my-project", type: "managed-dedicated" }],
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
const result = await detectProjectType({
|
|
84
|
-
authToken: "token",
|
|
85
|
-
projectName: "my-project",
|
|
86
|
-
});
|
|
87
|
-
assert.strictEqual(result, "managed-dedicated");
|
|
88
|
-
assert.strictEqual(requests.length, 2);
|
|
89
|
-
assert.match(requests[1], /accountName=resolved-account/);
|
|
90
|
-
});
|
|
91
|
-
it("does not overwrite an existing projectType", async () => {
|
|
92
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
93
|
-
await writeFile(configPath, `{
|
|
94
|
-
// Keep this comment.
|
|
95
|
-
"version": 1,
|
|
96
|
-
"projectType": "managed-edge"
|
|
97
|
-
}
|
|
98
|
-
`, "utf-8");
|
|
99
|
-
await updateProjectType(testDir, "managed-dedicated");
|
|
100
|
-
const contents = await readFile(configPath, "utf-8");
|
|
101
|
-
assert.match(contents, /Keep this comment/);
|
|
102
|
-
assert.match(contents, /"projectType": "managed-edge"/);
|
|
103
|
-
});
|
|
104
|
-
it("adds projectType when it is missing", async () => {
|
|
105
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
106
|
-
await writeFile(configPath, `{
|
|
107
|
-
// Keep this comment.
|
|
108
|
-
"version": 1
|
|
109
|
-
}
|
|
110
|
-
`, "utf-8");
|
|
111
|
-
await updateProjectType(testDir, "managed-dedicated");
|
|
112
|
-
const contents = await readFile(configPath, "utf-8");
|
|
113
|
-
assert.match(contents, /Keep this comment/);
|
|
114
|
-
assert.match(contents, /"version": 1,/);
|
|
115
|
-
assert.match(contents, /"projectType": "managed-dedicated"/);
|
|
116
|
-
});
|
|
117
|
-
it("skips detection when projectType is already configured", async () => {
|
|
118
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
119
|
-
await writeFile(configPath, `{
|
|
120
|
-
"version": 1,
|
|
121
|
-
"projectType": "managed-dedicated"
|
|
122
|
-
}
|
|
123
|
-
`, "utf-8");
|
|
124
|
-
const fetchMock = mock.method(globalThis, "fetch", async () => {
|
|
125
|
-
throw new Error("Project type detection should not run");
|
|
126
|
-
});
|
|
127
|
-
await syncProjectTypeForLink({
|
|
128
|
-
sourceDirectory: testDir,
|
|
129
|
-
accountName: "my-account",
|
|
130
|
-
authToken: "token",
|
|
131
|
-
projectName: "my-project",
|
|
132
|
-
});
|
|
133
|
-
const contents = await readFile(configPath, "utf-8");
|
|
134
|
-
assert.match(contents, /"projectType": "managed-dedicated"/);
|
|
135
|
-
assert.strictEqual(fetchMock.mock.callCount(), 0);
|
|
136
|
-
});
|
|
137
|
-
it("recognizes projectType in JSONC with a trailing comma", async () => {
|
|
138
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
139
|
-
const originalContents = `{
|
|
140
|
-
"version": 1,
|
|
141
|
-
"projectType": "managed-dedicated",
|
|
142
|
-
}
|
|
143
|
-
`;
|
|
144
|
-
await writeFile(configPath, originalContents, "utf-8");
|
|
145
|
-
const fetchMock = mock.method(globalThis, "fetch", async () => {
|
|
146
|
-
throw new Error("Project type detection should not run");
|
|
147
|
-
});
|
|
148
|
-
await syncProjectTypeForLink({
|
|
149
|
-
sourceDirectory: testDir,
|
|
150
|
-
accountName: "my-account",
|
|
151
|
-
authToken: "token",
|
|
152
|
-
projectName: "my-project",
|
|
153
|
-
});
|
|
154
|
-
assert.strictEqual(await readFile(configPath, "utf-8"), originalContents);
|
|
155
|
-
assert.strictEqual(fetchMock.mock.callCount(), 0);
|
|
156
|
-
});
|
|
157
|
-
it("persists a project type confirmed by the API", async () => {
|
|
158
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
159
|
-
await writeFile(configPath, '{\n "version": 1\n}\n', "utf-8");
|
|
160
|
-
mock.method(globalThis, "fetch", async () => {
|
|
161
|
-
return Response.json({
|
|
162
|
-
data: [{ name: "my-project", type: "managed-edge" }],
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
await syncProjectTypeForLink({
|
|
166
|
-
sourceDirectory: testDir,
|
|
167
|
-
accountName: "my-account",
|
|
168
|
-
authToken: "token",
|
|
169
|
-
projectName: "my-project",
|
|
170
|
-
});
|
|
171
|
-
const contents = await readFile(configPath, "utf-8");
|
|
172
|
-
assert.match(contents, /"projectType": "managed-edge"/);
|
|
173
|
-
});
|
|
174
|
-
it("does not persist the managed-edge fallback when detection fails", async () => {
|
|
175
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
176
|
-
const originalContents = '{\n "version": 1\n}\n';
|
|
177
|
-
await writeFile(configPath, originalContents, "utf-8");
|
|
178
|
-
mock.method(globalThis, "fetch", async () => {
|
|
179
|
-
throw new Error("offline");
|
|
180
|
-
});
|
|
181
|
-
await syncProjectTypeForLink({
|
|
182
|
-
sourceDirectory: testDir,
|
|
183
|
-
accountName: "my-account",
|
|
184
|
-
authToken: "token",
|
|
185
|
-
projectName: "my-project",
|
|
186
|
-
});
|
|
187
|
-
assert.strictEqual(await readFile(configPath, "utf-8"), originalContents);
|
|
188
|
-
});
|
|
189
|
-
it("does not persist a fallback for an unrecognized API project type", async () => {
|
|
190
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
191
|
-
const originalContents = '{\n "version": 1\n}\n';
|
|
192
|
-
await writeFile(configPath, originalContents, "utf-8");
|
|
193
|
-
mock.method(globalThis, "fetch", async () => {
|
|
194
|
-
return Response.json({
|
|
195
|
-
data: [{ name: "my-project", type: "self-hosted" }],
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
await syncProjectTypeForLink({
|
|
199
|
-
sourceDirectory: testDir,
|
|
200
|
-
accountName: "my-account",
|
|
201
|
-
authToken: "token",
|
|
202
|
-
projectName: "my-project",
|
|
203
|
-
});
|
|
204
|
-
assert.strictEqual(await readFile(configPath, "utf-8"), originalContents);
|
|
205
|
-
});
|
|
206
|
-
it("does not modify malformed JSONC", async () => {
|
|
207
|
-
const configPath = join(testDir, "zuplo.jsonc");
|
|
208
|
-
const originalContents = `{
|
|
209
|
-
"version": 1,
|
|
210
|
-
`;
|
|
211
|
-
await writeFile(configPath, originalContents, "utf-8");
|
|
212
|
-
const fetchMock = mock.method(globalThis, "fetch", async () => {
|
|
213
|
-
throw new Error("Project type detection should not run");
|
|
214
|
-
});
|
|
215
|
-
await syncProjectTypeForLink({
|
|
216
|
-
sourceDirectory: testDir,
|
|
217
|
-
accountName: "my-account",
|
|
218
|
-
authToken: "token",
|
|
219
|
-
projectName: "my-project",
|
|
220
|
-
});
|
|
221
|
-
assert.strictEqual(await readFile(configPath, "utf-8"), originalContents);
|
|
222
|
-
assert.strictEqual(fetchMock.mock.callCount(), 0);
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
//# sourceMappingURL=project-type.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"project-type.test.js","sourceRoot":"","sources":["../../src/link/project-type.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert\";\nimport { mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { afterEach, beforeEach, describe, it, mock } from \"node:test\";\nimport {\n detectProjectType,\n syncProjectTypeForLink,\n updateProjectType,\n} from \"./project-type.js\";\n\ndescribe(\"link project type detection\", () => {\n let testDir: string;\n\n beforeEach(async () => {\n testDir = await mkdtemp(join(tmpdir(), \"zuplo-dev-project-type-test-\"));\n });\n\n afterEach(async () => {\n mock.restoreAll();\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"detects a managed-dedicated project\", async () => {\n mock.method(globalThis, \"fetch\", async () => {\n return Response.json({\n data: [\n { name: \"other-project\", type: \"managed-edge\" },\n { name: \"my-project\", type: \"managed-dedicated\" },\n ],\n });\n });\n\n const result = await detectProjectType({\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(result, \"managed-dedicated\");\n });\n\n it(\"uses the explicitly designated project when multiple projects exist\", async () => {\n mock.method(globalThis, \"fetch\", async () => {\n return Response.json({\n data: [\n { name: \"linked-project\", type: \"managed-dedicated\" },\n { name: \"explicit-project\", type: \"managed-edge\" },\n ],\n });\n });\n\n const result = await detectProjectType({\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"explicit-project\",\n });\n\n assert.strictEqual(result, \"managed-edge\");\n });\n\n it(\"defaults self-hosted and unknown project types to managed-edge\", async () => {\n mock.method(globalThis, \"fetch\", async () => {\n return Response.json({\n data: [{ name: \"my-project\", type: \"self-hosted\" }],\n });\n });\n\n const result = await detectProjectType({\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(result, \"managed-edge\");\n });\n\n it(\"defaults to managed-edge when running offline\", async () => {\n mock.method(globalThis, \"fetch\", async () => {\n throw new Error(\"offline\");\n });\n\n const result = await detectProjectType({\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(result, \"managed-edge\");\n });\n\n it(\"resolves the account from who-am-i when it is not supplied\", async () => {\n const requests: string[] = [];\n mock.method(globalThis, \"fetch\", async (input: string | URL | Request) => {\n requests.push(String(input));\n if (String(input).endsWith(\"/v1/who-am-i\")) {\n return Response.json({ account: \"resolved-account\" });\n }\n return Response.json({\n data: [{ name: \"my-project\", type: \"managed-dedicated\" }],\n });\n });\n\n const result = await detectProjectType({\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(result, \"managed-dedicated\");\n assert.strictEqual(requests.length, 2);\n assert.match(requests[1], /accountName=resolved-account/);\n });\n\n it(\"does not overwrite an existing projectType\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n await writeFile(\n configPath,\n `{\n // Keep this comment.\n \"version\": 1,\n \"projectType\": \"managed-edge\"\n}\n`,\n \"utf-8\"\n );\n\n await updateProjectType(testDir, \"managed-dedicated\");\n\n const contents = await readFile(configPath, \"utf-8\");\n assert.match(contents, /Keep this comment/);\n assert.match(contents, /\"projectType\": \"managed-edge\"/);\n });\n\n it(\"adds projectType when it is missing\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n await writeFile(\n configPath,\n `{\n // Keep this comment.\n \"version\": 1\n}\n`,\n \"utf-8\"\n );\n\n await updateProjectType(testDir, \"managed-dedicated\");\n\n const contents = await readFile(configPath, \"utf-8\");\n assert.match(contents, /Keep this comment/);\n assert.match(contents, /\"version\": 1,/);\n assert.match(contents, /\"projectType\": \"managed-dedicated\"/);\n });\n\n it(\"skips detection when projectType is already configured\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n await writeFile(\n configPath,\n `{\n \"version\": 1,\n \"projectType\": \"managed-dedicated\"\n}\n`,\n \"utf-8\"\n );\n const fetchMock = mock.method(globalThis, \"fetch\", async () => {\n throw new Error(\"Project type detection should not run\");\n });\n\n await syncProjectTypeForLink({\n sourceDirectory: testDir,\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n const contents = await readFile(configPath, \"utf-8\");\n assert.match(contents, /\"projectType\": \"managed-dedicated\"/);\n assert.strictEqual(fetchMock.mock.callCount(), 0);\n });\n\n it(\"recognizes projectType in JSONC with a trailing comma\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n const originalContents = `{\n \"version\": 1,\n \"projectType\": \"managed-dedicated\",\n}\n`;\n await writeFile(configPath, originalContents, \"utf-8\");\n const fetchMock = mock.method(globalThis, \"fetch\", async () => {\n throw new Error(\"Project type detection should not run\");\n });\n\n await syncProjectTypeForLink({\n sourceDirectory: testDir,\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(await readFile(configPath, \"utf-8\"), originalContents);\n assert.strictEqual(fetchMock.mock.callCount(), 0);\n });\n\n it(\"persists a project type confirmed by the API\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n await writeFile(configPath, '{\\n \"version\": 1\\n}\\n', \"utf-8\");\n mock.method(globalThis, \"fetch\", async () => {\n return Response.json({\n data: [{ name: \"my-project\", type: \"managed-edge\" }],\n });\n });\n\n await syncProjectTypeForLink({\n sourceDirectory: testDir,\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n const contents = await readFile(configPath, \"utf-8\");\n assert.match(contents, /\"projectType\": \"managed-edge\"/);\n });\n\n it(\"does not persist the managed-edge fallback when detection fails\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n const originalContents = '{\\n \"version\": 1\\n}\\n';\n await writeFile(configPath, originalContents, \"utf-8\");\n mock.method(globalThis, \"fetch\", async () => {\n throw new Error(\"offline\");\n });\n\n await syncProjectTypeForLink({\n sourceDirectory: testDir,\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(await readFile(configPath, \"utf-8\"), originalContents);\n });\n\n it(\"does not persist a fallback for an unrecognized API project type\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n const originalContents = '{\\n \"version\": 1\\n}\\n';\n await writeFile(configPath, originalContents, \"utf-8\");\n mock.method(globalThis, \"fetch\", async () => {\n return Response.json({\n data: [{ name: \"my-project\", type: \"self-hosted\" }],\n });\n });\n\n await syncProjectTypeForLink({\n sourceDirectory: testDir,\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(await readFile(configPath, \"utf-8\"), originalContents);\n });\n\n it(\"does not modify malformed JSONC\", async () => {\n const configPath = join(testDir, \"zuplo.jsonc\");\n const originalContents = `{\n \"version\": 1,\n`;\n await writeFile(configPath, originalContents, \"utf-8\");\n const fetchMock = mock.method(globalThis, \"fetch\", async () => {\n throw new Error(\"Project type detection should not run\");\n });\n\n await syncProjectTypeForLink({\n sourceDirectory: testDir,\n accountName: \"my-account\",\n authToken: \"token\",\n projectName: \"my-project\",\n });\n\n assert.strictEqual(await readFile(configPath, \"utf-8\"), originalContents);\n assert.strictEqual(fetchMock.mock.callCount(), 0);\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-binary.test.d.ts","sourceRoot":"","sources":["../../src/lint/resolve-binary.test.ts"],"names":[],"mappings":""}
|