@supatype/cli 0.1.6 → 0.1.9
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +152 -102
- package/.turbo/turbo-typecheck.log +1 -1
- package/LICENSE +202 -0
- package/deno.d.ts +52 -0
- package/dist/app/framework.js +1 -1
- package/dist/app/framework.js.map +1 -1
- package/dist/augmentation-generator.d.ts +22 -0
- package/dist/augmentation-generator.d.ts.map +1 -1
- package/dist/augmentation-generator.js +19 -5
- package/dist/augmentation-generator.js.map +1 -1
- package/dist/binary-cache.d.ts +42 -6
- package/dist/binary-cache.d.ts.map +1 -1
- package/dist/binary-cache.js +76 -44
- package/dist/binary-cache.js.map +1 -1
- package/dist/cache-clean.d.ts +15 -0
- package/dist/cache-clean.d.ts.map +1 -0
- package/dist/cache-clean.js +76 -0
- package/dist/cache-clean.js.map +1 -0
- package/dist/cache-pins.d.ts +51 -0
- package/dist/cache-pins.d.ts.map +1 -0
- package/dist/cache-pins.js +184 -0
- package/dist/cache-pins.js.map +1 -0
- package/dist/cli-artifacts.d.ts +32 -0
- package/dist/cli-artifacts.d.ts.map +1 -0
- package/dist/cli-artifacts.js +49 -0
- package/dist/cli-artifacts.js.map +1 -0
- package/dist/cli-install-method.d.ts +27 -0
- package/dist/cli-install-method.d.ts.map +1 -0
- package/dist/cli-install-method.js +78 -0
- package/dist/cli-install-method.js.map +1 -0
- package/dist/cli-package-version.d.ts +1 -1
- package/dist/cli-package-version.d.ts.map +1 -1
- package/dist/cli-package-version.js +6 -1
- package/dist/cli-package-version.js.map +1 -1
- package/dist/cli-standalone.d.ts +13 -4
- package/dist/cli-standalone.d.ts.map +1 -1
- package/dist/cli-standalone.js +86 -31
- package/dist/cli-standalone.js.map +1 -1
- package/dist/cli-version-embedded.d.ts +10 -0
- package/dist/cli-version-embedded.d.ts.map +1 -0
- package/dist/cli-version-embedded.js +13 -0
- package/dist/cli-version-embedded.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/cloud-credentials.d.ts +34 -0
- package/dist/cloud-credentials.d.ts.map +1 -0
- package/dist/cloud-credentials.js +139 -0
- package/dist/cloud-credentials.js.map +1 -0
- package/dist/commands/add.js +1 -1
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/admin.d.ts +11 -0
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +123 -21
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/adopt.js +1 -1
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/app.js +2 -2
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/cache.d.ts +1 -1
- package/dist/commands/cache.d.ts.map +1 -1
- package/dist/commands/cache.js +69 -73
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +32 -8
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/db.d.ts +3 -2
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +149 -3
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/deploy.d.ts +9 -9
- package/dist/commands/deploy.js +12 -12
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +3 -3
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +63 -23
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +28 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +60 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/engine.d.ts +1 -1
- package/dist/commands/engine.js +1 -1
- package/dist/commands/functions.d.ts +7 -0
- package/dist/commands/functions.d.ts.map +1 -1
- package/dist/commands/functions.js +45 -11
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +5 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/hooks.d.ts +12 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +118 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +64 -30
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/internal.d.ts +6 -0
- package/dist/commands/internal.d.ts.map +1 -0
- package/dist/commands/internal.js +22 -0
- package/dist/commands/internal.js.map +1 -0
- package/dist/commands/link-helpers.d.ts.map +1 -1
- package/dist/commands/link-helpers.js +8 -2
- package/dist/commands/link-helpers.js.map +1 -1
- package/dist/commands/login.d.ts +7 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +110 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +1 -1
- package/dist/commands/migrate.js +5 -5
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/pg.d.ts +1 -1
- package/dist/commands/pg.js +1 -1
- package/dist/commands/plugins.js +1 -1
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/pull.js +2 -2
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +110 -7
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/self-host.d.ts +1 -1
- package/dist/commands/self-host.js +1 -1
- package/dist/commands/self-update.d.ts +3 -2
- package/dist/commands/self-update.d.ts.map +1 -1
- package/dist/commands/self-update.js +31 -16
- package/dist/commands/self-update.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/update.d.ts +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -4
- package/dist/config.js.map +1 -1
- package/dist/db-preflight.d.ts +78 -0
- package/dist/db-preflight.d.ts.map +1 -0
- package/dist/db-preflight.js +452 -0
- package/dist/db-preflight.js.map +1 -0
- package/dist/dev-compose.d.ts +4 -4
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +143 -88
- package/dist/dev-compose.js.map +1 -1
- package/dist/dev-log-filter.d.ts +1 -1
- package/dist/dev-log-filter.d.ts.map +1 -1
- package/dist/dev-log-filter.js +1 -1
- package/dist/dev-log-filter.js.map +1 -1
- package/dist/dev-ports.d.ts +2 -2
- package/dist/dev-ports.d.ts.map +1 -1
- package/dist/dev-ports.js +2 -2
- package/dist/dev-ports.js.map +1 -1
- package/dist/dev-session.d.ts +5 -5
- package/dist/dev-session.d.ts.map +1 -1
- package/dist/dev-session.js +6 -6
- package/dist/dev-session.js.map +1 -1
- package/dist/dev-shutdown.d.ts +5 -5
- package/dist/dev-shutdown.d.ts.map +1 -1
- package/dist/dev-shutdown.js +7 -7
- package/dist/dev-shutdown.js.map +1 -1
- package/dist/dev-task-colors.d.ts +1 -1
- package/dist/dev-task-colors.d.ts.map +1 -1
- package/dist/dev-task-colors.js +1 -1
- package/dist/dev-task-colors.js.map +1 -1
- package/dist/docker-postgres.d.ts +5 -5
- package/dist/docker-postgres.d.ts.map +1 -1
- package/dist/docker-postgres.js +5 -5
- package/dist/docker-postgres.js.map +1 -1
- package/dist/docker-runtime.d.ts +2 -2
- package/dist/docker-runtime.d.ts.map +1 -1
- package/dist/docker-runtime.js +5 -5
- package/dist/docker-runtime.js.map +1 -1
- package/dist/engine-client.d.ts +1 -1
- package/dist/engine-client.js +3 -3
- package/dist/engine-client.js.map +1 -1
- package/dist/engine-push-output.js +1 -1
- package/dist/engine-push-output.js.map +1 -1
- package/dist/ensure-binary.d.ts.map +1 -1
- package/dist/ensure-binary.js +17 -0
- package/dist/ensure-binary.js.map +1 -1
- package/dist/ensure-component-binaries.js +1 -1
- package/dist/ensure-component-binaries.js.map +1 -1
- package/dist/env-file.d.ts +40 -2
- package/dist/env-file.d.ts.map +1 -1
- package/dist/env-file.js +132 -11
- package/dist/env-file.js.map +1 -1
- package/dist/field-masking-tier.d.ts +50 -0
- package/dist/field-masking-tier.d.ts.map +1 -0
- package/dist/field-masking-tier.js +91 -0
- package/dist/field-masking-tier.js.map +1 -0
- package/dist/functions-deno-types.d.ts +24 -0
- package/dist/functions-deno-types.d.ts.map +1 -0
- package/dist/functions-deno-types.js +155 -0
- package/dist/functions-deno-types.js.map +1 -0
- package/dist/functions-router-gen.js +1 -1
- package/dist/gitignore.d.ts +2 -2
- package/dist/gitignore.d.ts.map +1 -1
- package/dist/gitignore.js +3 -3
- package/dist/gitignore.js.map +1 -1
- package/dist/hook-upload.d.ts +30 -0
- package/dist/hook-upload.d.ts.map +1 -0
- package/dist/hook-upload.js +86 -0
- package/dist/hook-upload.js.map +1 -0
- package/dist/hooks-generator.d.ts +8 -0
- package/dist/hooks-generator.d.ts.map +1 -0
- package/dist/hooks-generator.js +332 -0
- package/dist/hooks-generator.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/init-project-detect.d.ts +1 -1
- package/dist/init-project-detect.d.ts.map +1 -1
- package/dist/init-project-detect.js +1 -1
- package/dist/init-project-detect.js.map +1 -1
- package/dist/link.d.ts +4 -0
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +2 -0
- package/dist/link.js.map +1 -1
- package/dist/local-secrets.d.ts +71 -0
- package/dist/local-secrets.d.ts.map +1 -0
- package/dist/local-secrets.js +100 -0
- package/dist/local-secrets.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +20 -0
- package/dist/main.js.map +1 -0
- package/dist/model-hooks.d.ts +73 -0
- package/dist/model-hooks.d.ts.map +1 -0
- package/dist/model-hooks.js +211 -0
- package/dist/model-hooks.js.map +1 -0
- package/dist/pgbouncer-userlist.d.ts +1 -1
- package/dist/pgbouncer-userlist.d.ts.map +1 -1
- package/dist/pgbouncer-userlist.js +2 -2
- package/dist/pgbouncer-userlist.js.map +1 -1
- package/dist/postgres-ctl.d.ts +12 -1
- package/dist/postgres-ctl.d.ts.map +1 -1
- package/dist/postgres-ctl.js +28 -5
- package/dist/postgres-ctl.js.map +1 -1
- package/dist/process-manager.d.ts +2 -2
- package/dist/process-manager.d.ts.map +1 -1
- package/dist/process-manager.js +4 -4
- package/dist/process-manager.js.map +1 -1
- package/dist/project-config.d.ts +122 -2
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +150 -1
- package/dist/project-config.js.map +1 -1
- package/dist/pull-utils.d.ts +2 -2
- package/dist/pull-utils.d.ts.map +1 -1
- package/dist/pull-utils.js +4 -4
- package/dist/pull-utils.js.map +1 -1
- package/dist/realtime-launch.js +1 -1
- package/dist/realtime-launch.js.map +1 -1
- package/dist/release-pins.d.ts +1 -1
- package/dist/release-pins.js +2 -2
- package/dist/release-pins.js.map +1 -1
- package/dist/resolve-api-url.js +1 -1
- package/dist/resolve-api-url.js.map +1 -1
- package/dist/resolve-target.d.ts +4 -0
- package/dist/resolve-target.d.ts.map +1 -1
- package/dist/resolve-target.js +69 -73
- package/dist/resolve-target.js.map +1 -1
- package/dist/rest-cache-admin.js +2 -2
- package/dist/rest-cache-admin.js.map +1 -1
- package/dist/runtime-routes.d.ts +1 -1
- package/dist/runtime-routes.js +1 -1
- package/dist/schema-ast-v2.d.ts +5 -4
- package/dist/schema-ast-v2.d.ts.map +1 -1
- package/dist/schema-ast-v2.js +5 -3
- package/dist/schema-ast-v2.js.map +1 -1
- package/dist/schema-push-lock.d.ts.map +1 -1
- package/dist/schema-push-lock.js +43 -16
- package/dist/schema-push-lock.js.map +1 -1
- package/dist/scripts/postinstall.d.ts +1 -1
- package/dist/scripts/postinstall.js +1 -1
- package/dist/self-host-compose.d.ts +26 -2
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +305 -73
- package/dist/self-host-compose.js.map +1 -1
- package/dist/service-role-check.d.ts +21 -0
- package/dist/service-role-check.d.ts.map +1 -0
- package/dist/service-role-check.js +85 -0
- package/dist/service-role-check.js.map +1 -0
- package/dist/storage-provision.d.ts +1 -1
- package/dist/storage-provision.js +3 -3
- package/dist/storage-provision.js.map +1 -1
- package/dist/studio-dev-server.d.ts +1 -1
- package/dist/studio-dev-server.d.ts.map +1 -1
- package/dist/systemd.d.ts +1 -1
- package/dist/systemd.js +1 -1
- package/dist/target-client.d.ts +17 -0
- package/dist/target-client.d.ts.map +1 -1
- package/dist/target-client.js +69 -17
- package/dist/target-client.js.map +1 -1
- package/dist/tsx-runner.js +1 -1
- package/dist/tsx-runner.js.map +1 -1
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +738 -34
- package/dist/type-extractor.js.map +1 -1
- package/dist/type-resolver.js +1 -1
- package/dist/type-resolver.js.map +1 -1
- package/dist/ui/brand.d.ts +1 -1
- package/dist/ui/brand.js +1 -1
- package/dist/ui/components/LogoWordmark.d.ts +1 -1
- package/dist/ui/components/LogoWordmark.d.ts.map +1 -1
- package/dist/ui/components/LogoWordmark.js +1 -1
- package/dist/ui/components/LogoWordmark.js.map +1 -1
- package/dist/ui/components/SelectField.js +1 -1
- package/dist/ui/components/SelectField.js.map +1 -1
- package/dist/ui/confirm.d.ts +1 -1
- package/dist/ui/confirm.js +1 -1
- package/dist/ui/fatal.d.ts +1 -1
- package/dist/ui/fatal.d.ts.map +1 -1
- package/dist/ui/fatal.js +1 -1
- package/dist/ui/fatal.js.map +1 -1
- package/dist/ui/flows/prompt-fields.js +1 -1
- package/dist/ui/flows/prompt-fields.js.map +1 -1
- package/dist/ui/interactive.d.ts +1 -1
- package/dist/ui/interactive.d.ts.map +1 -1
- package/dist/ui/interactive.js +1 -1
- package/dist/ui/interactive.js.map +1 -1
- package/dist/ui/progress.d.ts +1 -1
- package/dist/ui/progress.js +1 -1
- package/dist/ui/runtime/command-chrome.js +2 -2
- package/dist/ui/runtime/command-chrome.js.map +1 -1
- package/dist/ui/runtime/run-clack-flow.js +1 -1
- package/dist/ui/runtime/run-clack-flow.js.map +1 -1
- package/dist/ui/runtime/stdin-after-ink.d.ts.map +1 -1
- package/dist/ui/runtime/stdin-after-ink.js +4 -2
- package/dist/ui/runtime/stdin-after-ink.js.map +1 -1
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.js +1 -1
- package/dist/valkey-sidecar.d.ts +1 -1
- package/dist/valkey-sidecar.d.ts.map +1 -1
- package/dist/valkey-sidecar.js +2 -2
- package/dist/valkey-sidecar.js.map +1 -1
- package/package.json +6 -2
- package/scripts/build-release-artifacts.sh +112 -0
- package/scripts/generate-homebrew-formula.mjs +123 -0
- package/scripts/mirror-deno-release.sh +1 -1
- package/src/TYPE-RESOLUTION.md +31 -31
- package/src/app/framework.ts +1 -1
- package/src/augmentation-generator.ts +19 -6
- package/src/binary-cache.ts +94 -47
- package/src/cache-clean.ts +81 -0
- package/src/cache-pins.ts +243 -0
- package/src/cli-artifacts.ts +65 -0
- package/src/cli-install-method.ts +87 -0
- package/src/cli-package-version.ts +5 -1
- package/src/cli-standalone.ts +116 -34
- package/src/cli-version-embedded.ts +12 -0
- package/src/cli.ts +7 -1
- package/src/cloud-credentials.ts +183 -0
- package/src/commands/add.ts +1 -1
- package/src/commands/admin.ts +142 -27
- package/src/commands/adopt.ts +1 -1
- package/src/commands/app.ts +2 -2
- package/src/commands/cache.ts +92 -77
- package/src/commands/cloud.ts +32 -8
- package/src/commands/db.ts +164 -3
- package/src/commands/deploy.ts +12 -12
- package/src/commands/dev.ts +72 -23
- package/src/commands/doctor.ts +69 -3
- package/src/commands/engine.ts +1 -1
- package/src/commands/functions.ts +47 -10
- package/src/commands/generate.ts +5 -1
- package/src/commands/hooks.ts +138 -0
- package/src/commands/init.ts +65 -31
- package/src/commands/internal.ts +23 -0
- package/src/commands/link-helpers.ts +9 -2
- package/src/commands/login.ts +127 -0
- package/src/commands/logs.ts +1 -1
- package/src/commands/migrate.ts +5 -5
- package/src/commands/pg.ts +1 -1
- package/src/commands/plugins.ts +1 -1
- package/src/commands/pull.ts +2 -2
- package/src/commands/push.ts +124 -7
- package/src/commands/self-host.ts +1 -1
- package/src/commands/self-update.ts +41 -19
- package/src/commands/status.ts +1 -1
- package/src/commands/update.ts +1 -1
- package/src/config.ts +23 -4
- package/src/db-preflight.ts +575 -0
- package/src/dev-compose.ts +158 -89
- package/src/dev-log-filter.ts +1 -1
- package/src/dev-ports.ts +3 -3
- package/src/dev-session.ts +6 -6
- package/src/dev-shutdown.ts +8 -8
- package/src/dev-task-colors.ts +1 -1
- package/src/docker-postgres.ts +6 -6
- package/src/docker-runtime.ts +5 -5
- package/src/engine-client.ts +3 -3
- package/src/engine-push-output.ts +1 -1
- package/src/ensure-binary.ts +20 -0
- package/src/ensure-component-binaries.ts +1 -1
- package/src/env-file.ts +157 -11
- package/src/field-masking-tier.ts +107 -0
- package/src/functions-deno-types.ts +188 -0
- package/src/functions-router-gen.ts +1 -1
- package/src/gitignore.ts +3 -3
- package/src/hook-upload.ts +107 -0
- package/src/hooks-generator.ts +352 -0
- package/src/index.ts +1 -1
- package/src/init-project-detect.ts +1 -1
- package/src/link.ts +7 -0
- package/src/local-secrets.ts +104 -0
- package/src/main.ts +20 -0
- package/src/model-hooks.ts +260 -0
- package/src/pgbouncer-userlist.ts +2 -2
- package/src/postgres-ctl.ts +32 -5
- package/src/process-manager.ts +4 -4
- package/src/project-config.ts +237 -3
- package/src/pull-utils.ts +4 -4
- package/src/realtime-launch.ts +1 -1
- package/src/release-pins.ts +2 -2
- package/src/resolve-api-url.ts +1 -1
- package/src/resolve-target.ts +113 -68
- package/src/rest-cache-admin.ts +2 -2
- package/src/runtime-routes.ts +2 -2
- package/src/schema-ast-v2.ts +8 -5
- package/src/schema-push-lock.ts +56 -17
- package/src/scripts/postinstall.ts +1 -1
- package/src/self-host-compose.ts +348 -72
- package/src/service-role-check.ts +111 -0
- package/src/storage-provision.ts +3 -3
- package/src/studio-dev-server.ts +1 -1
- package/src/systemd.ts +1 -1
- package/src/target-client.ts +105 -18
- package/src/tsx-runner.ts +1 -1
- package/src/type-extractor.ts +885 -30
- package/src/type-resolver.ts +1 -1
- package/src/ui/README.md +1 -1
- package/src/ui/brand.ts +1 -1
- package/src/ui/components/LogoWordmark.tsx +1 -1
- package/src/ui/components/SelectField.tsx +1 -1
- package/src/ui/confirm.ts +1 -1
- package/src/ui/fatal.ts +1 -1
- package/src/ui/flows/prompt-fields.tsx +1 -1
- package/src/ui/interactive.ts +1 -1
- package/src/ui/progress.ts +1 -1
- package/src/ui/runtime/command-chrome.ts +2 -2
- package/src/ui/runtime/run-clack-flow.tsx +1 -1
- package/src/ui/runtime/stdin-after-ink.ts +4 -2
- package/src/ui/theme.ts +1 -1
- package/src/valkey-sidecar.ts +2 -2
- package/tests/access-composition.test.ts +667 -0
- package/tests/admin-studio-membership.test.ts +121 -0
- package/tests/api-schemas.test.ts +83 -0
- package/tests/archive-name-alias.test.ts +42 -0
- package/tests/augmentation-generator.test.ts +28 -0
- package/tests/cache-clean.test.ts +206 -0
- package/tests/cli-help.test.ts +11 -2
- package/tests/cli-install-method.test.ts +66 -0
- package/tests/command-chrome-coverage.test.ts +31 -26
- package/tests/command-chrome-wrap.test.ts +1 -0
- package/tests/db-preflight.test.ts +72 -0
- package/tests/doctor-render.test.ts +62 -0
- package/tests/doctor-service-role.test.ts +55 -0
- package/tests/engine-push-output.test.ts +1 -1
- package/tests/env-file.test.ts +121 -0
- package/tests/external-database-compose.test.ts +184 -0
- package/tests/external-database-config.test.ts +154 -0
- package/tests/field-masking-tier.test.ts +184 -0
- package/tests/functions-deno-types.test.ts +197 -0
- package/tests/homebrew-formula.test.ts +100 -0
- package/tests/hook-upload.test.ts +125 -0
- package/tests/hooks-generator.test.ts +212 -0
- package/tests/init.test.ts +5 -2
- package/tests/keys.test.ts +8 -2
- package/tests/local-secrets.test.ts +92 -0
- package/tests/model-hooks.test.ts +322 -0
- package/tests/runtime-contract.test.ts +113 -1
- package/tests/service-role-check.test.ts +109 -0
- package/tests/service-role-routes.test.ts +51 -0
- package/tests/storage-provision.test.ts +1 -1
- package/tests/target-client-refresh.test.ts +94 -0
- package/tests/type-extractor.test.ts +187 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +7 -1
- package/scripts/build-release-bundle.mjs +0 -27
- package/tests/engine-distribution.test.ts +0 -418
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
interface AstModel {
|
|
1
|
+
export interface AstModel {
|
|
2
2
|
name?: string
|
|
3
3
|
tableName?: string
|
|
4
4
|
fields: Record<string, Record<string, unknown>>
|
|
@@ -11,7 +11,14 @@ interface AstShape {
|
|
|
11
11
|
models?: AstModel[]
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Shared with the hooks generator on purpose.
|
|
16
|
+
*
|
|
17
|
+
* A hook's `row` must be the same shape the client sees for that table, and two copies of this logic
|
|
18
|
+
* would drift: the client would gain a column type the hook handler did not, which is the failure
|
|
19
|
+
* mode this codebase has already paid for once.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveTableName(model: AstModel): string {
|
|
15
22
|
const fromAnnotations = model.annotations?.db?.tableName
|
|
16
23
|
if (typeof fromAnnotations === "string" && fromAnnotations.length > 0) return fromAnnotations
|
|
17
24
|
if (typeof model.tableName === "string" && model.tableName.length > 0) return model.tableName
|
|
@@ -36,7 +43,7 @@ export function generateClientAugmentation(ast: unknown): string {
|
|
|
36
43
|
.sort((a, b) => a.tableName.localeCompare(b.tableName))
|
|
37
44
|
|
|
38
45
|
const lines: string[] = []
|
|
39
|
-
lines.push("// Generated by supatype CLI
|
|
46
|
+
lines.push("// Generated by supatype CLI, do not edit manually.")
|
|
40
47
|
lines.push("")
|
|
41
48
|
lines.push("declare module \"@supatype/client\" {")
|
|
42
49
|
lines.push(" interface SupatypeModels {")
|
|
@@ -58,7 +65,7 @@ export function generateClientAugmentation(ast: unknown): string {
|
|
|
58
65
|
return lines.join("\n")
|
|
59
66
|
}
|
|
60
67
|
|
|
61
|
-
function generateRowType(fields: Record<string, Record<string, unknown>>): string {
|
|
68
|
+
export function generateRowType(fields: Record<string, Record<string, unknown>>): string {
|
|
62
69
|
const entries = Object.entries(fields).sort(([a], [b]) => a.localeCompare(b))
|
|
63
70
|
if (entries.length === 0) return "Record<string, unknown>"
|
|
64
71
|
const body = entries
|
|
@@ -71,7 +78,7 @@ function insertColumnOptionalOnInsert(meta: Record<string, unknown>): boolean {
|
|
|
71
78
|
return meta["default"] !== undefined || fieldServerGenerated(meta)
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
function generateInsertType(fields: Record<string, Record<string, unknown>>): string {
|
|
81
|
+
export function generateInsertType(fields: Record<string, Record<string, unknown>>): string {
|
|
75
82
|
const entries = Object.entries(fields).sort(([a], [b]) => a.localeCompare(b))
|
|
76
83
|
if (entries.length === 0) return "Record<string, unknown>"
|
|
77
84
|
const body = entries
|
|
@@ -83,7 +90,7 @@ function generateInsertType(fields: Record<string, Record<string, unknown>>): st
|
|
|
83
90
|
return `{\n${body}\n}`
|
|
84
91
|
}
|
|
85
92
|
|
|
86
|
-
function generateUpdateType(fields: Record<string, Record<string, unknown>>): string {
|
|
93
|
+
export function generateUpdateType(fields: Record<string, Record<string, unknown>>): string {
|
|
87
94
|
const entries = Object.entries(fields).sort(([a], [b]) => a.localeCompare(b))
|
|
88
95
|
if (entries.length === 0) return "Record<string, unknown>"
|
|
89
96
|
const body = entries
|
|
@@ -96,6 +103,12 @@ function toTsType(meta: Record<string, unknown>): string {
|
|
|
96
103
|
const kind = typeof meta["kind"] === "string" ? meta["kind"] : "json"
|
|
97
104
|
const required = meta["required"] === true
|
|
98
105
|
const base = (() => {
|
|
106
|
+
// A field that knows its own shape says so. Without this, everything stored as JSONB collapses
|
|
107
|
+
// to `Record<string, unknown>` in the generated row, so `Currency` would arrive as an opaque
|
|
108
|
+
// object rather than `{ amount: string; code: "USD" }`, and the schema's precision would be
|
|
109
|
+
// lost exactly where a caller reads it.
|
|
110
|
+
const declared = meta["tsType"]
|
|
111
|
+
if (typeof declared === "string" && declared.length > 0) return declared
|
|
99
112
|
switch (kind) {
|
|
100
113
|
case "uuid":
|
|
101
114
|
case "slug":
|
package/src/binary-cache.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Binary cache
|
|
2
|
+
* Binary cache: manages supatype component binaries.
|
|
3
3
|
*
|
|
4
4
|
* Components: engine, server, postgres, deno, realtime.
|
|
5
5
|
* Cache root: ~/.supatype/cache/{component}/{version}/
|
|
@@ -71,7 +71,7 @@ export function hasMeaningfulOverrides(config: SupatypeProjectConfig): boolean {
|
|
|
71
71
|
return false
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
/** Lines for a startup banner
|
|
74
|
+
/** Lines for a startup banner, non-empty override paths only. */
|
|
75
75
|
export function describeActiveOverrides(config: SupatypeProjectConfig): string[] {
|
|
76
76
|
const o = config.overrides
|
|
77
77
|
if (!o) return []
|
|
@@ -196,6 +196,26 @@ function binaryName(component: Component, version: string, platform: PlatformId)
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Names a published archive may carry, most-canonical first.
|
|
201
|
+
*
|
|
202
|
+
* `supatype-postgres` published the Intel macOS archive as `darwin-x86_64` while every other platform
|
|
203
|
+
* used `amd64`, the spelling the CLI derives from `process.arch === "x64"`. Releases already on the CDN
|
|
204
|
+
* carry the old name, so both are accepted and the *signed* checksums manifest decides which exists.
|
|
205
|
+
* Nothing is guessed: the URL and the hash always come from the same manifest entry.
|
|
206
|
+
*/
|
|
207
|
+
export function archiveNameCandidates(
|
|
208
|
+
component: Component,
|
|
209
|
+
version: string,
|
|
210
|
+
platform: PlatformId,
|
|
211
|
+
): string[] {
|
|
212
|
+
const canonical = binaryName(component, version, platform)
|
|
213
|
+
if (component === "postgres" && platform.os === "darwin" && platform.arch === "amd64") {
|
|
214
|
+
return [canonical, canonical.replace("darwin-amd64", "darwin-x86_64")]
|
|
215
|
+
}
|
|
216
|
+
return [canonical]
|
|
217
|
+
}
|
|
218
|
+
|
|
199
219
|
// ---------------------------------------------------------------------------
|
|
200
220
|
// Platform detection
|
|
201
221
|
// ---------------------------------------------------------------------------
|
|
@@ -222,9 +242,9 @@ export function currentPlatform(): PlatformId {
|
|
|
222
242
|
* Resolve the binary path for a component.
|
|
223
243
|
*
|
|
224
244
|
* Resolution order:
|
|
225
|
-
* 1. config.overrides?.[component]
|
|
245
|
+
* 1. config.overrides?.[component]: local build path (must exist)
|
|
226
246
|
* 2. Cached binary at ~/.supatype/cache/{component}/{version}/
|
|
227
|
-
* 3. Throws
|
|
247
|
+
* 3. Throws, so the caller should call download() first.
|
|
228
248
|
*
|
|
229
249
|
* Hard error if any meaningful `overrides` entry is set while the project is linked to cloud
|
|
230
250
|
* (`project.ref`, `.supatype/cloud.json`, or `.supatype/linked.json`).
|
|
@@ -332,7 +352,7 @@ async function acquireDownloadSlot(
|
|
|
332
352
|
|
|
333
353
|
if (isDownloadInProgress(component, version)) {
|
|
334
354
|
console.log(
|
|
335
|
-
`[supatype] ${component} v${version} is downloading in another process
|
|
355
|
+
`[supatype] ${component} v${version} is downloading in another process, waiting...`,
|
|
336
356
|
)
|
|
337
357
|
const outcome = await waitForComponentDownload(component, version, isReady, (c) => {
|
|
338
358
|
console.log(`[supatype] Still waiting for ${c} download...`)
|
|
@@ -344,7 +364,7 @@ async function acquireDownloadSlot(
|
|
|
344
364
|
)
|
|
345
365
|
}
|
|
346
366
|
console.warn(
|
|
347
|
-
`[supatype] ${component} v${version} download did not finish in the other process
|
|
367
|
+
`[supatype] ${component} v${version} download did not finish in the other process, retrying.`,
|
|
348
368
|
)
|
|
349
369
|
continue
|
|
350
370
|
}
|
|
@@ -364,7 +384,7 @@ export async function download(
|
|
|
364
384
|
): Promise<string> {
|
|
365
385
|
if (version === VERSION_PIN_LOCAL) {
|
|
366
386
|
throw new Error(
|
|
367
|
-
`cannot download CDN binary when version is "${VERSION_PIN_LOCAL}"
|
|
387
|
+
`cannot download CDN binary when version is "${VERSION_PIN_LOCAL}": set overrides.${component === "postgres" ? "postgres_dir" : component} or pin a semver`,
|
|
368
388
|
)
|
|
369
389
|
}
|
|
370
390
|
|
|
@@ -380,7 +400,7 @@ export async function download(
|
|
|
380
400
|
return destPath
|
|
381
401
|
}
|
|
382
402
|
console.warn(
|
|
383
|
-
`[supatype] ${component} v${version} cache invalid
|
|
403
|
+
`[supatype] ${component} v${version} cache invalid, re-downloading (${destPath}).`,
|
|
384
404
|
)
|
|
385
405
|
unlinkSync(destPath)
|
|
386
406
|
}
|
|
@@ -390,7 +410,6 @@ export async function download(
|
|
|
390
410
|
return destPath
|
|
391
411
|
}
|
|
392
412
|
|
|
393
|
-
const binaryUrl = `${CDN_BASE}${CDN_PATHS[component](version, platform)}`
|
|
394
413
|
const checksumsUrl = `${CDN_BASE}${checksumsDirPath(component, version)}`
|
|
395
414
|
const minisigUrl = `${checksumsUrl}.minisig`
|
|
396
415
|
|
|
@@ -399,15 +418,20 @@ export async function download(
|
|
|
399
418
|
const tmpPath = destPath + ".tmp"
|
|
400
419
|
try {
|
|
401
420
|
// ── Fetch checksums + optional minisig (retried on transient failures) ───
|
|
402
|
-
const
|
|
403
|
-
fetchChecksums(checksumsUrl, minisigUrl,
|
|
421
|
+
const match = await withRetry(() =>
|
|
422
|
+
fetchChecksums(checksumsUrl, minisigUrl, archiveNameCandidates(component, version, platform)),
|
|
404
423
|
)
|
|
405
424
|
|
|
425
|
+
// The directory from the path template, the filename from the manifest: a release published under
|
|
426
|
+
// a legacy name is fetched under that name rather than one the CLI assumed.
|
|
427
|
+
const cdnDir = CDN_PATHS[component](version, platform).replace(/\/[^/]+$/, "")
|
|
428
|
+
const binaryUrl = `${CDN_BASE}${cdnDir}/${match.filename}`
|
|
429
|
+
|
|
406
430
|
// ── Stream-download binary with progress (retried on transient failures) ─
|
|
407
431
|
await withRetry(() => streamToFileWithProgress(binaryUrl, tmpPath))
|
|
408
432
|
|
|
409
433
|
// ── Verify SHA256 ────────────────────────────────────────────────────────
|
|
410
|
-
await verifyChecksum(tmpPath,
|
|
434
|
+
await verifyChecksum(tmpPath, match.checksum, component)
|
|
411
435
|
|
|
412
436
|
writeFileSync(destPath, readFileSync(tmpPath))
|
|
413
437
|
|
|
@@ -437,11 +461,19 @@ export async function download(
|
|
|
437
461
|
* Fetch checksums.sha256, optionally verify its minisign signature, and
|
|
438
462
|
* return the expected SHA256 for `binaryFilename`.
|
|
439
463
|
*/
|
|
440
|
-
|
|
464
|
+
/**
|
|
465
|
+
* Fetch a checksums manifest and verify its minisign signature, returning the entry for one of
|
|
466
|
+
* `binaryFilenames`.
|
|
467
|
+
*
|
|
468
|
+
* Exported so the standalone CLI download path enforces the same rule as component downloads.
|
|
469
|
+
* It previously verified nothing at all, which made the CLI stricter about a postgres archive
|
|
470
|
+
* than about overwriting its own executable.
|
|
471
|
+
*/
|
|
472
|
+
export async function fetchChecksums(
|
|
441
473
|
checksumsUrl: string,
|
|
442
474
|
minisigUrl: string,
|
|
443
|
-
|
|
444
|
-
): Promise<
|
|
475
|
+
binaryFilenames: string | string[],
|
|
476
|
+
): Promise<ChecksumMatch> {
|
|
445
477
|
const csResp = await fetch(checksumsUrl)
|
|
446
478
|
if (!csResp.ok) {
|
|
447
479
|
throw new Error(`Failed to fetch checksums from ${checksumsUrl}: HTTP ${csResp.status}`)
|
|
@@ -452,16 +484,16 @@ async function fetchChecksums(
|
|
|
452
484
|
if (!pubKey) {
|
|
453
485
|
// Fail closed: a missing public key means we cannot verify authenticity, only
|
|
454
486
|
// integrity (SHA256). Published builds always embed the key, so this only
|
|
455
|
-
// happens in source/contributor builds
|
|
487
|
+
// happens in source/contributor builds. Never silently downgrade.
|
|
456
488
|
if (process.env["SUPATYPE_ALLOW_UNVERIFIED_DOWNLOADS"] === "1") {
|
|
457
489
|
console.warn(
|
|
458
|
-
"[supatype] \u26a0 SUPATYPE_ALLOW_UNVERIFIED_DOWNLOADS=1
|
|
490
|
+
"[supatype] \u26a0 SUPATYPE_ALLOW_UNVERIFIED_DOWNLOADS=1: no minisign public " +
|
|
459
491
|
"key configured; verifying SHA256 only (authenticity NOT checked).",
|
|
460
492
|
)
|
|
461
|
-
return extractChecksum(checksumsText,
|
|
493
|
+
return extractChecksum(checksumsText, binaryFilenames)
|
|
462
494
|
}
|
|
463
495
|
throw new Error(
|
|
464
|
-
"No minisign public key configured
|
|
496
|
+
"No minisign public key configured, so cannot verify release authenticity.\n" +
|
|
465
497
|
"Published @supatype/cli builds embed the key automatically; if you are building " +
|
|
466
498
|
"from source, set SUPATYPE_RELEASE_PUBLIC_KEY to the release public key, or set " +
|
|
467
499
|
"SUPATYPE_ALLOW_UNVERIFIED_DOWNLOADS=1 to download with SHA256-only verification (unsafe).",
|
|
@@ -479,7 +511,7 @@ async function fetchChecksums(
|
|
|
479
511
|
const sigText = await sigResp.text()
|
|
480
512
|
verifyMinisign(Buffer.from(checksumsText, "utf8"), sigText, pubKey)
|
|
481
513
|
|
|
482
|
-
return extractChecksum(checksumsText,
|
|
514
|
+
return extractChecksum(checksumsText, binaryFilenames)
|
|
483
515
|
}
|
|
484
516
|
|
|
485
517
|
// ---------------------------------------------------------------------------
|
|
@@ -487,7 +519,7 @@ async function fetchChecksums(
|
|
|
487
519
|
// ---------------------------------------------------------------------------
|
|
488
520
|
|
|
489
521
|
/**
|
|
490
|
-
* Ed25519 SPKI DER prefix
|
|
522
|
+
* Ed25519 SPKI DER prefix, wraps a raw 32-byte public key into the
|
|
491
523
|
* SubjectPublicKeyInfo structure that Node.js crypto.createPublicKey expects.
|
|
492
524
|
*
|
|
493
525
|
* Breakdown:
|
|
@@ -515,7 +547,7 @@ export function verifyMinisign(fileBytes: Buffer, sigFileContent: string, pubKey
|
|
|
515
547
|
|
|
516
548
|
// Parse signature file:
|
|
517
549
|
// line 0: untrusted comment
|
|
518
|
-
// line 1: base64 sig bytes
|
|
550
|
+
// line 1: base64 sig bytes: [2 algo][8 keyId][64 Ed25519 sig]
|
|
519
551
|
// line 2: trusted comment
|
|
520
552
|
// line 3: base64 global sig (over sig bytes + trusted comment)
|
|
521
553
|
const sigLines = sigFileContent.trim().split("\n")
|
|
@@ -528,12 +560,12 @@ export function verifyMinisign(fileBytes: Buffer, sigFileContent: string, pubKey
|
|
|
528
560
|
const signature = sigBytes.subarray(10, 74)
|
|
529
561
|
|
|
530
562
|
// Both Ed25519 modes are supported:
|
|
531
|
-
// "Ed" (0x45, 0x64)
|
|
532
|
-
// "ED" (0x45, 0x44)
|
|
563
|
+
// "Ed" (0x45, 0x64) legacy: signature is over the raw file bytes.
|
|
564
|
+
// "ED" (0x45, 0x44) prehashed: signature is over BLAKE2b-512(file).
|
|
533
565
|
// Modern minisign (and our release pipeline) default to prehashed mode.
|
|
534
566
|
if (algo[0] !== 0x45 || (algo[1] !== 0x64 && algo[1] !== 0x44)) {
|
|
535
567
|
throw new Error(
|
|
536
|
-
"Unsupported minisign algorithm
|
|
568
|
+
"Unsupported minisign algorithm, expected Ed25519 ('Ed' legacy or 'ED' prehashed).\n" +
|
|
537
569
|
`Got: 0x${algo[0]?.toString(16)}${algo[1]?.toString(16)}`,
|
|
538
570
|
)
|
|
539
571
|
}
|
|
@@ -541,7 +573,7 @@ export function verifyMinisign(fileBytes: Buffer, sigFileContent: string, pubKey
|
|
|
541
573
|
|
|
542
574
|
if (!sigKeyId.equals(pkKeyId)) {
|
|
543
575
|
throw new Error(
|
|
544
|
-
"Minisign key ID mismatch
|
|
576
|
+
"Minisign key ID mismatch: the signature was produced with a different key.\n" +
|
|
545
577
|
"This could indicate a compromised release. Do not proceed.",
|
|
546
578
|
)
|
|
547
579
|
}
|
|
@@ -558,7 +590,7 @@ export function verifyMinisign(fileBytes: Buffer, sigFileContent: string, pubKey
|
|
|
558
590
|
const valid = cryptoVerify(null, signedData, keyObject, signature)
|
|
559
591
|
if (!valid) {
|
|
560
592
|
throw new Error(
|
|
561
|
-
"Minisign signature verification FAILED
|
|
593
|
+
"Minisign signature verification FAILED: the checksum file may have been tampered with.\n" +
|
|
562
594
|
"This could indicate a supply chain attack. Aborting download.",
|
|
563
595
|
)
|
|
564
596
|
}
|
|
@@ -566,22 +598,37 @@ export function verifyMinisign(fileBytes: Buffer, sigFileContent: string, pubKey
|
|
|
566
598
|
|
|
567
599
|
/**
|
|
568
600
|
* Extract the SHA256 hash for `filename` from a checksums.sha256 file.
|
|
569
|
-
* Format: `<hash> <filename>` (sha256sum output, two spaces)
|
|
601
|
+
* Format: `<hash> <filename>` (sha256sum output, two spaces), or `<hash> *<filename>` when
|
|
602
|
+
* the publisher used binary mode.
|
|
603
|
+
*
|
|
604
|
+
* Exported so the standalone CLI download path parses the manifest the same way rather than
|
|
605
|
+
* carrying a second implementation.
|
|
570
606
|
*/
|
|
571
|
-
function extractChecksum(
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
607
|
+
export function extractChecksum(
|
|
608
|
+
checksumsText: string,
|
|
609
|
+
filenames: string | string[],
|
|
610
|
+
): ChecksumMatch {
|
|
611
|
+
const targets = (Array.isArray(filenames) ? filenames : [filenames]).map((f) => basename(f))
|
|
612
|
+
for (const target of targets) {
|
|
613
|
+
for (const line of checksumsText.split("\n")) {
|
|
614
|
+
const parts = line.trim().split(/\s+/)
|
|
615
|
+
if (parts.length >= 2 && parts[1]?.replace(/^\*/, "") === target) {
|
|
616
|
+
return { filename: target, checksum: parts[0]! }
|
|
617
|
+
}
|
|
577
618
|
}
|
|
578
619
|
}
|
|
579
620
|
throw new Error(
|
|
580
|
-
`Checksum not found for "${
|
|
621
|
+
`Checksum not found for ${targets.map((t) => `"${t}"`).join(" or ")} in checksums.sha256.\n` +
|
|
581
622
|
"The checksums file may be from a different release.",
|
|
582
623
|
)
|
|
583
624
|
}
|
|
584
625
|
|
|
626
|
+
/** Which published name matched, and its hash, both from the same signed manifest entry. */
|
|
627
|
+
export interface ChecksumMatch {
|
|
628
|
+
filename: string
|
|
629
|
+
checksum: string
|
|
630
|
+
}
|
|
631
|
+
|
|
585
632
|
// ---------------------------------------------------------------------------
|
|
586
633
|
// Streaming download with progress bar
|
|
587
634
|
// ---------------------------------------------------------------------------
|
|
@@ -658,9 +705,9 @@ export function validateArtifactFormat(
|
|
|
658
705
|
|
|
659
706
|
/**
|
|
660
707
|
* Per-component CDN artifact shapes:
|
|
661
|
-
* engine, server, deno, realtime
|
|
662
|
-
* postgres (unix)
|
|
663
|
-
* postgres (windows)
|
|
708
|
+
* engine, server, deno, realtime: native executable (ELF / Mach-O / PE)
|
|
709
|
+
* postgres (unix) .tar.gz (gzip)
|
|
710
|
+
* postgres (windows) .zip
|
|
664
711
|
*/
|
|
665
712
|
function assertArtifactFormat(
|
|
666
713
|
component: Component,
|
|
@@ -687,7 +734,7 @@ function assertGzipArchive(filePath: string): void {
|
|
|
687
734
|
if (magic[0] !== 0x1f || magic[1] !== 0x8b) {
|
|
688
735
|
throw new Error(
|
|
689
736
|
"Downloaded postgres file is not a gzip archive (bad magic bytes). " +
|
|
690
|
-
"The CDN object may be corrupt or cached HTML
|
|
737
|
+
"The CDN object may be corrupt or cached HTML, so delete ~/.supatype/cache and retry.",
|
|
691
738
|
)
|
|
692
739
|
}
|
|
693
740
|
} finally {
|
|
@@ -704,7 +751,7 @@ function assertZipArchive(filePath: string): void {
|
|
|
704
751
|
if (magic[0] !== 0x50 || magic[1] !== 0x4b) {
|
|
705
752
|
throw new Error(
|
|
706
753
|
"Downloaded postgres file is not a zip archive (bad magic bytes). " +
|
|
707
|
-
"The CDN object may be corrupt or cached HTML
|
|
754
|
+
"The CDN object may be corrupt or cached HTML, so delete ~/.supatype/cache and retry.",
|
|
708
755
|
)
|
|
709
756
|
}
|
|
710
757
|
} finally {
|
|
@@ -727,14 +774,14 @@ function assertNativeExecutable(
|
|
|
727
774
|
if (goCArchive) {
|
|
728
775
|
throw new Error(
|
|
729
776
|
`Downloaded ${component} file is a Go static archive (c-archive), not an executable. ` +
|
|
730
|
-
"The CDN object may be from a bad release build
|
|
777
|
+
"The CDN object may be from a bad release build, so delete ~/.supatype/cache and retry.",
|
|
731
778
|
)
|
|
732
779
|
}
|
|
733
780
|
if (platform.os === "windows") {
|
|
734
781
|
if (magic[0] !== 0x4d || magic[1] !== 0x5a) {
|
|
735
782
|
throw new Error(
|
|
736
783
|
`Downloaded ${component} file is not a Windows PE executable (bad magic bytes). ` +
|
|
737
|
-
"The CDN object may be corrupt or cached HTML
|
|
784
|
+
"The CDN object may be corrupt or cached HTML, so delete ~/.supatype/cache and retry.",
|
|
738
785
|
)
|
|
739
786
|
}
|
|
740
787
|
return
|
|
@@ -745,7 +792,7 @@ function assertNativeExecutable(
|
|
|
745
792
|
if (!elf) {
|
|
746
793
|
throw new Error(
|
|
747
794
|
`Downloaded ${component} file is not an ELF executable (bad magic bytes). ` +
|
|
748
|
-
"The CDN object may be corrupt or cached HTML
|
|
795
|
+
"The CDN object may be corrupt or cached HTML, so delete ~/.supatype/cache and retry.",
|
|
749
796
|
)
|
|
750
797
|
}
|
|
751
798
|
return
|
|
@@ -759,7 +806,7 @@ function assertNativeExecutable(
|
|
|
759
806
|
if (!macho) {
|
|
760
807
|
throw new Error(
|
|
761
808
|
`Downloaded ${component} file is not a Mach-O executable (bad magic bytes). ` +
|
|
762
|
-
"The CDN object may be corrupt or cached HTML
|
|
809
|
+
"The CDN object may be corrupt or cached HTML, so delete ~/.supatype/cache and retry.",
|
|
763
810
|
)
|
|
764
811
|
}
|
|
765
812
|
} finally {
|
|
@@ -805,7 +852,7 @@ async function withRetry<T>(fn: () => Promise<T>, attempts = 3): Promise<T> {
|
|
|
805
852
|
// ---------------------------------------------------------------------------
|
|
806
853
|
|
|
807
854
|
/**
|
|
808
|
-
* On Windows, Git Bash represents paths as /c/Users
|
|
855
|
+
* On Windows, Git Bash represents paths as /c/Users/..., convert to C:\Users\...
|
|
809
856
|
*/
|
|
810
857
|
export function normalisePlatformPath(p: string): string {
|
|
811
858
|
let result = p
|
|
@@ -899,7 +946,7 @@ export async function fetchAllLatestVersions(): Promise<Partial<Record<Component
|
|
|
899
946
|
*/
|
|
900
947
|
/**
|
|
901
948
|
* Verify cached binaries for the current platform (used by integration CI).
|
|
902
|
-
* Only checks components present in `versions
|
|
949
|
+
* Only checks components present in `versions`; unpublished CDN components
|
|
903
950
|
* (no latest.json yet) are skipped with a log so CI can land before first release.
|
|
904
951
|
* Throws if a pinned component is missing from cache or fails format checks.
|
|
905
952
|
*/
|
|
@@ -912,7 +959,7 @@ export function verifyCachedBinaries(versions: Partial<ComponentVersions> | unde
|
|
|
912
959
|
const version = versions[component]
|
|
913
960
|
if (typeof version !== "string" || version.trim() === "") {
|
|
914
961
|
console.log(
|
|
915
|
-
`[supatype] skipping verify for ${component} (no version
|
|
962
|
+
`[supatype] skipping verify for ${component} (no version, CDN latest.json not published yet)`,
|
|
916
963
|
)
|
|
917
964
|
continue
|
|
918
965
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for `supatype cache list` / `cache clean` (shared sizing + formatting).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readdirSync, statSync } from "node:fs"
|
|
6
|
+
import { join } from "node:path"
|
|
7
|
+
import { BINARY_COMPONENTS, type Component } from "./components.js"
|
|
8
|
+
import { cacheRoot } from "./binary-cache.js"
|
|
9
|
+
import { isVersionPinned, loadPinnedVersionsForProjects, resolveCacheProjectDirs } from "./cache-pins.js"
|
|
10
|
+
|
|
11
|
+
export function dirSize(dir: string): number {
|
|
12
|
+
let total = 0
|
|
13
|
+
try {
|
|
14
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
15
|
+
const full = join(dir, entry.name)
|
|
16
|
+
if (entry.isDirectory()) {
|
|
17
|
+
total += dirSize(full)
|
|
18
|
+
} else {
|
|
19
|
+
total += statSync(full).size
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
} catch {
|
|
23
|
+
// skip unreadable
|
|
24
|
+
}
|
|
25
|
+
return total
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function formatBytes(bytes: number): string {
|
|
29
|
+
if (bytes < 1024) return `${bytes} B`
|
|
30
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
|
|
31
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
|
|
32
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function listCacheEntries(projectDirs: string[]): Array<{
|
|
36
|
+
component: Component
|
|
37
|
+
version: string
|
|
38
|
+
bytes: number
|
|
39
|
+
pinned: boolean
|
|
40
|
+
}> {
|
|
41
|
+
const root = cacheRoot()
|
|
42
|
+
const { protectedVersions } = loadPinnedVersionsForProjects(projectDirs)
|
|
43
|
+
const entries: Array<{ component: Component; version: string; bytes: number; pinned: boolean }> = []
|
|
44
|
+
|
|
45
|
+
for (const component of BINARY_COMPONENTS) {
|
|
46
|
+
const compDir = join(root, component)
|
|
47
|
+
if (!statExists(compDir)) continue
|
|
48
|
+
|
|
49
|
+
for (const version of readdirSync(compDir)) {
|
|
50
|
+
const vDir = join(compDir, version)
|
|
51
|
+
if (!statIsDir(vDir)) continue
|
|
52
|
+
entries.push({
|
|
53
|
+
component,
|
|
54
|
+
version,
|
|
55
|
+
bytes: dirSize(vDir),
|
|
56
|
+
pinned: protectedVersions.get(component)?.has(version) ?? false,
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return entries
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function statExists(path: string): boolean {
|
|
65
|
+
try {
|
|
66
|
+
statSync(path)
|
|
67
|
+
return true
|
|
68
|
+
} catch {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function statIsDir(path: string): boolean {
|
|
74
|
+
try {
|
|
75
|
+
return statSync(path).isDirectory()
|
|
76
|
+
} catch {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { BINARY_COMPONENTS, resolveCacheProjectDirs }
|