@synteq/cli 0.1.6 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/run.js +61 -2
- package/dist/api/client.d.ts +363 -5
- package/dist/api/client.js +559 -44
- package/dist/api/client.js.map +1 -1
- package/dist/api/factory.d.ts +3 -0
- package/dist/api/factory.js +6 -3
- package/dist/api/factory.js.map +1 -1
- package/dist/api/types.d.ts +896 -4
- package/dist/apps-support/deploy.d.ts +197 -0
- package/dist/apps-support/deploy.js +639 -0
- package/dist/apps-support/deploy.js.map +1 -0
- package/dist/apps-support/dotenv.d.ts +67 -0
- package/dist/apps-support/dotenv.js +136 -0
- package/dist/apps-support/dotenv.js.map +1 -0
- package/dist/apps-support/env-rollout.d.ts +18 -0
- package/dist/apps-support/env-rollout.js +52 -0
- package/dist/apps-support/env-rollout.js.map +1 -0
- package/dist/apps-support/git.d.ts +14 -0
- package/dist/apps-support/git.js +25 -0
- package/dist/apps-support/git.js.map +1 -0
- package/dist/apps-support/link.d.ts +25 -0
- package/dist/apps-support/link.js +39 -0
- package/dist/apps-support/link.js.map +1 -0
- package/dist/apps-support/log-stream.d.ts +25 -0
- package/dist/apps-support/log-stream.js +85 -0
- package/dist/apps-support/log-stream.js.map +1 -0
- package/dist/apps-support/paid-app.d.ts +64 -0
- package/dist/apps-support/paid-app.js +195 -0
- package/dist/apps-support/paid-app.js.map +1 -0
- package/dist/apps-support/plans.d.ts +44 -0
- package/dist/apps-support/plans.js +43 -0
- package/dist/apps-support/plans.js.map +1 -0
- package/dist/apps-support/resolve.d.ts +10 -0
- package/dist/apps-support/resolve.js +53 -0
- package/dist/apps-support/resolve.js.map +1 -0
- package/dist/apps-support/time.d.ts +20 -0
- package/dist/apps-support/time.js +82 -0
- package/dist/apps-support/time.js.map +1 -0
- package/dist/auth/scope.d.ts +19 -0
- package/dist/auth/scope.js +69 -0
- package/dist/auth/scope.js.map +1 -0
- package/dist/auth/tokens.d.ts +3 -0
- package/dist/auth/tokens.js +6 -4
- package/dist/auth/tokens.js.map +1 -1
- package/dist/base/command.d.ts +36 -1
- package/dist/base/command.js +132 -0
- package/dist/base/command.js.map +1 -1
- package/dist/commands/account/index.d.ts +1 -0
- package/dist/commands/account/index.js +1 -0
- package/dist/commands/account/index.js.map +1 -1
- package/dist/commands/account/show.d.ts +1 -0
- package/dist/commands/account/show.js +1 -0
- package/dist/commands/account/show.js.map +1 -1
- package/dist/commands/agents.d.ts +10 -0
- package/dist/commands/agents.js +53 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/api.d.ts +1 -1
- package/dist/commands/api.js +6 -4
- package/dist/commands/api.js.map +1 -1
- package/dist/commands/app/deployment/list.d.ts +14 -0
- package/dist/commands/app/deployment/list.js +45 -0
- package/dist/commands/app/deployment/list.js.map +1 -0
- package/dist/commands/app/deployment/rollback.d.ts +18 -0
- package/dist/commands/app/deployment/rollback.js +57 -0
- package/dist/commands/app/deployment/rollback.js.map +1 -0
- package/dist/commands/app/deployment/show.d.ts +26 -0
- package/dist/commands/app/deployment/show.js +98 -0
- package/dist/commands/app/deployment/show.js.map +1 -0
- package/dist/commands/app/domain/add.d.ts +17 -0
- package/dist/commands/app/domain/add.js +59 -0
- package/dist/commands/app/domain/add.js.map +1 -0
- package/dist/commands/app/domain/list.d.ts +14 -0
- package/dist/commands/app/domain/list.js +42 -0
- package/dist/commands/app/domain/list.js.map +1 -0
- package/dist/commands/app/domain/remove.d.ts +16 -0
- package/dist/commands/app/domain/remove.js +51 -0
- package/dist/commands/app/domain/remove.js.map +1 -0
- package/dist/commands/app/domain/verify.d.ts +15 -0
- package/dist/commands/app/domain/verify.js +39 -0
- package/dist/commands/app/domain/verify.js.map +1 -0
- package/dist/commands/app/env/add.d.ts +22 -0
- package/dist/commands/app/env/add.js +103 -0
- package/dist/commands/app/env/add.js.map +1 -0
- package/dist/commands/app/env/list.d.ts +17 -0
- package/dist/commands/app/env/list.js +40 -0
- package/dist/commands/app/env/list.js.map +1 -0
- package/dist/commands/app/env/reveal.d.ts +17 -0
- package/dist/commands/app/env/reveal.js +40 -0
- package/dist/commands/app/env/reveal.js.map +1 -0
- package/dist/commands/app/env/rm.d.ts +16 -0
- package/dist/commands/app/env/rm.js +48 -0
- package/dist/commands/app/env/rm.js.map +1 -0
- package/dist/commands/app/health.d.ts +14 -0
- package/dist/commands/app/health.js +40 -0
- package/dist/commands/app/health.js.map +1 -0
- package/dist/commands/app/index.d.ts +6 -0
- package/dist/commands/app/index.js +7 -0
- package/dist/commands/app/index.js.map +1 -0
- package/dist/commands/app/link.d.ts +22 -0
- package/dist/commands/app/link.js +31 -0
- package/dist/commands/app/link.js.map +1 -0
- package/dist/commands/app/logs.d.ts +25 -0
- package/dist/commands/app/logs.js +121 -0
- package/dist/commands/app/logs.js.map +1 -0
- package/dist/commands/app/metrics.d.ts +21 -0
- package/dist/commands/app/metrics.js +123 -0
- package/dist/commands/app/metrics.js.map +1 -0
- package/dist/commands/app/plan/change.d.ts +18 -0
- package/dist/commands/app/plan/change.js +79 -0
- package/dist/commands/app/plan/change.js.map +1 -0
- package/dist/commands/app/plan/show.d.ts +14 -0
- package/dist/commands/app/plan/show.js +40 -0
- package/dist/commands/app/plan/show.js.map +1 -0
- package/dist/commands/app/settings/set.d.ts +25 -0
- package/dist/commands/app/settings/set.js +96 -0
- package/dist/commands/app/settings/set.js.map +1 -0
- package/dist/commands/app/settings/show.d.ts +14 -0
- package/dist/commands/app/settings/show.js +48 -0
- package/dist/commands/app/settings/show.js.map +1 -0
- package/dist/commands/app/unlink.d.ts +8 -0
- package/dist/commands/app/unlink.js +25 -0
- package/dist/commands/app/unlink.js.map +1 -0
- package/dist/commands/apps/create.d.ts +26 -0
- package/dist/commands/apps/create.js +91 -0
- package/dist/commands/apps/create.js.map +1 -0
- package/dist/commands/apps/list.d.ts +16 -0
- package/dist/commands/apps/list.js +54 -0
- package/dist/commands/apps/list.js.map +1 -0
- package/dist/commands/baremetal/activity.d.ts +14 -0
- package/dist/commands/baremetal/activity.js +53 -0
- package/dist/commands/baremetal/activity.js.map +1 -0
- package/dist/commands/baremetal/bandwidth.d.ts +10 -0
- package/dist/commands/baremetal/bandwidth.js +86 -0
- package/dist/commands/baremetal/bandwidth.js.map +1 -0
- package/dist/commands/baremetal/console.d.ts +20 -0
- package/dist/commands/baremetal/console.js +72 -0
- package/dist/commands/baremetal/console.js.map +1 -0
- package/dist/commands/baremetal/details.d.ts +11 -0
- package/dist/commands/baremetal/details.js +116 -0
- package/dist/commands/baremetal/details.js.map +1 -0
- package/dist/commands/baremetal/index.d.ts +5 -0
- package/dist/commands/baremetal/index.js +6 -0
- package/dist/commands/baremetal/index.js.map +1 -0
- package/dist/commands/baremetal/install-password.d.ts +14 -0
- package/dist/commands/baremetal/install-password.js +80 -0
- package/dist/commands/baremetal/install-password.js.map +1 -0
- package/dist/commands/baremetal/list.d.ts +11 -0
- package/dist/commands/baremetal/list.js +59 -0
- package/dist/commands/baremetal/list.js.map +1 -0
- package/dist/commands/baremetal/order.d.ts +34 -0
- package/dist/commands/baremetal/order.js +394 -0
- package/dist/commands/baremetal/order.js.map +1 -0
- package/dist/commands/baremetal/power.d.ts +18 -0
- package/dist/commands/baremetal/power.js +168 -0
- package/dist/commands/baremetal/power.js.map +1 -0
- package/dist/commands/baremetal/reinstall.d.ts +21 -0
- package/dist/commands/baremetal/reinstall.js +168 -0
- package/dist/commands/baremetal/reinstall.js.map +1 -0
- package/dist/commands/catalog.d.ts +1 -0
- package/dist/commands/catalog.js +5 -0
- package/dist/commands/catalog.js.map +1 -1
- package/dist/commands/config/index.d.ts +1 -0
- package/dist/commands/config/index.js +1 -0
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/profile/add.d.ts +11 -0
- package/dist/commands/config/profile/add.js +51 -0
- package/dist/commands/config/profile/add.js.map +1 -0
- package/dist/commands/config/profile/list.d.ts +7 -0
- package/dist/commands/config/profile/list.js +29 -0
- package/dist/commands/config/profile/list.js.map +1 -0
- package/dist/commands/config/profile/remove.d.ts +11 -0
- package/dist/commands/config/profile/remove.js +35 -0
- package/dist/commands/config/profile/remove.js.map +1 -0
- package/dist/commands/config/profile/use.d.ts +10 -0
- package/dist/commands/config/profile/use.js +44 -0
- package/dist/commands/config/profile/use.js.map +1 -0
- package/dist/commands/config/set-api-url.d.ts +1 -0
- package/dist/commands/config/set-api-url.js +1 -0
- package/dist/commands/config/set-api-url.js.map +1 -1
- package/dist/commands/config/show.d.ts +1 -0
- package/dist/commands/config/show.js +5 -1
- package/dist/commands/config/show.js.map +1 -1
- package/dist/commands/credits/add.d.ts +1 -0
- package/dist/commands/credits/add.js +3 -2
- package/dist/commands/credits/add.js.map +1 -1
- package/dist/commands/credits/index.d.ts +1 -0
- package/dist/commands/credits/index.js +6 -1
- package/dist/commands/credits/index.js.map +1 -1
- package/dist/commands/credits/list.d.ts +1 -0
- package/dist/commands/credits/list.js +1 -0
- package/dist/commands/credits/list.js.map +1 -1
- package/dist/commands/deploy.d.ts +51 -0
- package/dist/commands/deploy.js +515 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/function/create.d.ts +29 -0
- package/dist/commands/function/create.js +113 -0
- package/dist/commands/function/create.js.map +1 -0
- package/dist/commands/function/credits/add.d.ts +29 -0
- package/dist/commands/function/credits/add.js +209 -0
- package/dist/commands/function/credits/add.js.map +1 -0
- package/dist/commands/function/credits/auto-reload.d.ts +27 -0
- package/dist/commands/function/credits/auto-reload.js +107 -0
- package/dist/commands/function/credits/auto-reload.js.map +1 -0
- package/dist/commands/function/credits/index.d.ts +22 -0
- package/dist/commands/function/credits/index.js +80 -0
- package/dist/commands/function/credits/index.js.map +1 -0
- package/dist/commands/function/cron/add.d.ts +19 -0
- package/dist/commands/function/cron/add.js +74 -0
- package/dist/commands/function/cron/add.js.map +1 -0
- package/dist/commands/function/cron/list.d.ts +12 -0
- package/dist/commands/function/cron/list.js +55 -0
- package/dist/commands/function/cron/list.js.map +1 -0
- package/dist/commands/function/cron/rm.d.ts +17 -0
- package/dist/commands/function/cron/rm.js +73 -0
- package/dist/commands/function/cron/rm.js.map +1 -0
- package/dist/commands/function/cron/run.d.ts +16 -0
- package/dist/commands/function/cron/run.js +59 -0
- package/dist/commands/function/cron/run.js.map +1 -0
- package/dist/commands/function/cron/update.d.ts +21 -0
- package/dist/commands/function/cron/update.js +87 -0
- package/dist/commands/function/cron/update.js.map +1 -0
- package/dist/commands/function/delete.d.ts +23 -0
- package/dist/commands/function/delete.js +90 -0
- package/dist/commands/function/delete.js.map +1 -0
- package/dist/commands/function/deploy.d.ts +64 -0
- package/dist/commands/function/deploy.js +608 -0
- package/dist/commands/function/deploy.js.map +1 -0
- package/dist/commands/function/env/list.d.ts +12 -0
- package/dist/commands/function/env/list.js +46 -0
- package/dist/commands/function/env/list.js.map +1 -0
- package/dist/commands/function/env/reveal.d.ts +21 -0
- package/dist/commands/function/env/reveal.js +54 -0
- package/dist/commands/function/env/reveal.js.map +1 -0
- package/dist/commands/function/env/rm.d.ts +17 -0
- package/dist/commands/function/env/rm.js +62 -0
- package/dist/commands/function/env/rm.js.map +1 -0
- package/dist/commands/function/env/set.d.ts +28 -0
- package/dist/commands/function/env/set.js +124 -0
- package/dist/commands/function/env/set.js.map +1 -0
- package/dist/commands/function/index.d.ts +14 -0
- package/dist/commands/function/index.js +11 -0
- package/dist/commands/function/index.js.map +1 -0
- package/dist/commands/function/init.d.ts +47 -0
- package/dist/commands/function/init.js +269 -0
- package/dist/commands/function/init.js.map +1 -0
- package/dist/commands/function/invoke.d.ts +29 -0
- package/dist/commands/function/invoke.js +138 -0
- package/dist/commands/function/invoke.js.map +1 -0
- package/dist/commands/function/link.d.ts +23 -0
- package/dist/commands/function/link.js +80 -0
- package/dist/commands/function/link.js.map +1 -0
- package/dist/commands/function/list.d.ts +16 -0
- package/dist/commands/function/list.js +55 -0
- package/dist/commands/function/list.js.map +1 -0
- package/dist/commands/function/logs.d.ts +29 -0
- package/dist/commands/function/logs.js +171 -0
- package/dist/commands/function/logs.js.map +1 -0
- package/dist/commands/function/pause.d.ts +19 -0
- package/dist/commands/function/pause.js +50 -0
- package/dist/commands/function/pause.js.map +1 -0
- package/dist/commands/function/releases.d.ts +15 -0
- package/dist/commands/function/releases.js +62 -0
- package/dist/commands/function/releases.js.map +1 -0
- package/dist/commands/function/resume.d.ts +16 -0
- package/dist/commands/function/resume.js +47 -0
- package/dist/commands/function/resume.js.map +1 -0
- package/dist/commands/function/rollback.d.ts +18 -0
- package/dist/commands/function/rollback.js +69 -0
- package/dist/commands/function/rollback.js.map +1 -0
- package/dist/commands/function/settings/set.d.ts +23 -0
- package/dist/commands/function/settings/set.js +119 -0
- package/dist/commands/function/settings/set.js.map +1 -0
- package/dist/commands/function/show.d.ts +15 -0
- package/dist/commands/function/show.js +80 -0
- package/dist/commands/function/show.js.map +1 -0
- package/dist/commands/function/unlink.d.ts +9 -0
- package/dist/commands/function/unlink.js +34 -0
- package/dist/commands/function/unlink.js.map +1 -0
- package/dist/commands/gpu/activity.d.ts +1 -0
- package/dist/commands/gpu/activity.js +1 -0
- package/dist/commands/gpu/activity.js.map +1 -1
- package/dist/commands/gpu/bandwidth.d.ts +1 -0
- package/dist/commands/gpu/bandwidth.js +1 -0
- package/dist/commands/gpu/bandwidth.js.map +1 -1
- package/dist/commands/gpu/boot-order.d.ts +1 -0
- package/dist/commands/gpu/boot-order.js +1 -0
- package/dist/commands/gpu/boot-order.js.map +1 -1
- package/dist/commands/gpu/console.d.ts +1 -0
- package/dist/commands/gpu/console.js +1 -0
- package/dist/commands/gpu/console.js.map +1 -1
- package/dist/commands/gpu/details.d.ts +1 -0
- package/dist/commands/gpu/details.js +1 -0
- package/dist/commands/gpu/details.js.map +1 -1
- package/dist/commands/gpu/index.d.ts +1 -0
- package/dist/commands/gpu/index.js +1 -0
- package/dist/commands/gpu/index.js.map +1 -1
- package/dist/commands/gpu/ip/add.d.ts +1 -0
- package/dist/commands/gpu/ip/add.js +1 -0
- package/dist/commands/gpu/ip/add.js.map +1 -1
- package/dist/commands/gpu/ip/list.d.ts +1 -0
- package/dist/commands/gpu/ip/list.js +1 -0
- package/dist/commands/gpu/ip/list.js.map +1 -1
- package/dist/commands/gpu/list.d.ts +1 -0
- package/dist/commands/gpu/list.js +1 -0
- package/dist/commands/gpu/list.js.map +1 -1
- package/dist/commands/gpu/order.d.ts +1 -0
- package/dist/commands/gpu/order.js +1 -0
- package/dist/commands/gpu/order.js.map +1 -1
- package/dist/commands/gpu/power.d.ts +1 -0
- package/dist/commands/gpu/power.js +1 -0
- package/dist/commands/gpu/power.js.map +1 -1
- package/dist/commands/gpu/reinstall.d.ts +1 -0
- package/dist/commands/gpu/reinstall.js +1 -0
- package/dist/commands/gpu/reinstall.js.map +1 -1
- package/dist/commands/gpu/resize.d.ts +1 -0
- package/dist/commands/gpu/resize.js +1 -0
- package/dist/commands/gpu/resize.js.map +1 -1
- package/dist/commands/gpu/stats.d.ts +1 -0
- package/dist/commands/gpu/stats.js +1 -0
- package/dist/commands/gpu/stats.js.map +1 -1
- package/dist/commands/help.d.ts +2 -0
- package/dist/commands/help.js +5 -0
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/instant-metal/activity.d.ts +1 -0
- package/dist/commands/instant-metal/activity.js +1 -0
- package/dist/commands/instant-metal/activity.js.map +1 -1
- package/dist/commands/instant-metal/bandwidth.d.ts +1 -0
- package/dist/commands/instant-metal/bandwidth.js +1 -0
- package/dist/commands/instant-metal/bandwidth.js.map +1 -1
- package/dist/commands/instant-metal/boot-order.d.ts +1 -0
- package/dist/commands/instant-metal/boot-order.js +1 -0
- package/dist/commands/instant-metal/boot-order.js.map +1 -1
- package/dist/commands/instant-metal/console.d.ts +1 -0
- package/dist/commands/instant-metal/console.js +1 -0
- package/dist/commands/instant-metal/console.js.map +1 -1
- package/dist/commands/instant-metal/details.d.ts +1 -0
- package/dist/commands/instant-metal/details.js +1 -0
- package/dist/commands/instant-metal/details.js.map +1 -1
- package/dist/commands/instant-metal/index.d.ts +1 -0
- package/dist/commands/instant-metal/index.js +1 -0
- package/dist/commands/instant-metal/index.js.map +1 -1
- package/dist/commands/instant-metal/ip/add.d.ts +1 -0
- package/dist/commands/instant-metal/ip/add.js +1 -0
- package/dist/commands/instant-metal/ip/add.js.map +1 -1
- package/dist/commands/instant-metal/ip/list.d.ts +1 -0
- package/dist/commands/instant-metal/ip/list.js +1 -0
- package/dist/commands/instant-metal/ip/list.js.map +1 -1
- package/dist/commands/instant-metal/list.d.ts +1 -0
- package/dist/commands/instant-metal/list.js +1 -0
- package/dist/commands/instant-metal/list.js.map +1 -1
- package/dist/commands/instant-metal/order.d.ts +1 -0
- package/dist/commands/instant-metal/order.js +1 -0
- package/dist/commands/instant-metal/order.js.map +1 -1
- package/dist/commands/instant-metal/power.d.ts +1 -0
- package/dist/commands/instant-metal/power.js +1 -0
- package/dist/commands/instant-metal/power.js.map +1 -1
- package/dist/commands/instant-metal/reinstall.d.ts +1 -0
- package/dist/commands/instant-metal/reinstall.js +1 -0
- package/dist/commands/instant-metal/reinstall.js.map +1 -1
- package/dist/commands/instant-metal/resize.d.ts +1 -0
- package/dist/commands/instant-metal/resize.js +1 -0
- package/dist/commands/instant-metal/resize.js.map +1 -1
- package/dist/commands/instant-metal/stats.d.ts +1 -0
- package/dist/commands/instant-metal/stats.js +1 -0
- package/dist/commands/instant-metal/stats.js.map +1 -1
- package/dist/commands/link.d.ts +77 -0
- package/dist/commands/link.js +530 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +10 -0
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts +1 -0
- package/dist/commands/logout.js +1 -0
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/order/gpu.d.ts +1 -0
- package/dist/commands/order/gpu.js +1 -0
- package/dist/commands/order/gpu.js.map +1 -1
- package/dist/commands/order/instant-metal.d.ts +1 -0
- package/dist/commands/order/instant-metal.js +1 -0
- package/dist/commands/order/instant-metal.js.map +1 -1
- package/dist/commands/order/storage.d.ts +1 -0
- package/dist/commands/order/storage.js +1 -0
- package/dist/commands/order/storage.js.map +1 -1
- package/dist/commands/order/vps.d.ts +1 -0
- package/dist/commands/order/vps.js +1 -0
- package/dist/commands/order/vps.js.map +1 -1
- package/dist/commands/order.d.ts +1 -0
- package/dist/commands/order.js +4 -1
- package/dist/commands/order.js.map +1 -1
- package/dist/commands/os-images.d.ts +1 -0
- package/dist/commands/os-images.js +3 -0
- package/dist/commands/os-images.js.map +1 -1
- package/dist/commands/payments/index.d.ts +1 -0
- package/dist/commands/payments/index.js +1 -0
- package/dist/commands/payments/index.js.map +1 -1
- package/dist/commands/payments/methods/add.d.ts +1 -0
- package/dist/commands/payments/methods/add.js +1 -0
- package/dist/commands/payments/methods/add.js.map +1 -1
- package/dist/commands/payments/methods/delete.d.ts +1 -0
- package/dist/commands/payments/methods/delete.js +3 -2
- package/dist/commands/payments/methods/delete.js.map +1 -1
- package/dist/commands/payments/methods/index.d.ts +1 -0
- package/dist/commands/payments/methods/index.js +1 -0
- package/dist/commands/payments/methods/index.js.map +1 -1
- package/dist/commands/payments/methods/list.d.ts +1 -0
- package/dist/commands/payments/methods/list.js +1 -0
- package/dist/commands/payments/methods/list.js.map +1 -1
- package/dist/commands/payments/methods/set-default.d.ts +1 -0
- package/dist/commands/payments/methods/set-default.js +1 -0
- package/dist/commands/payments/methods/set-default.js.map +1 -1
- package/dist/commands/projects/index.d.ts +1 -0
- package/dist/commands/projects/index.js +1 -0
- package/dist/commands/projects/index.js.map +1 -1
- package/dist/commands/projects/list.d.ts +1 -0
- package/dist/commands/projects/list.js +1 -0
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/resources.d.ts +1 -0
- package/dist/commands/resources.js +61 -7
- package/dist/commands/resources.js.map +1 -1
- package/dist/commands/settings/index.d.ts +1 -0
- package/dist/commands/settings/index.js +1 -0
- package/dist/commands/settings/index.js.map +1 -1
- package/dist/commands/settings/render-mode.d.ts +1 -0
- package/dist/commands/settings/render-mode.js +1 -0
- package/dist/commands/settings/render-mode.js.map +1 -1
- package/dist/commands/ssh-key/add.d.ts +1 -0
- package/dist/commands/ssh-key/add.js +1 -0
- package/dist/commands/ssh-key/add.js.map +1 -1
- package/dist/commands/ssh-key/delete.d.ts +1 -0
- package/dist/commands/ssh-key/delete.js +1 -0
- package/dist/commands/ssh-key/delete.js.map +1 -1
- package/dist/commands/ssh-key/list.d.ts +1 -0
- package/dist/commands/ssh-key/list.js +1 -0
- package/dist/commands/ssh-key/list.js.map +1 -1
- package/dist/commands/status.d.ts +12 -0
- package/dist/commands/status.js +71 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/storage/attach.d.ts +1 -0
- package/dist/commands/storage/attach.js +1 -0
- package/dist/commands/storage/attach.js.map +1 -1
- package/dist/commands/storage/detach.d.ts +1 -0
- package/dist/commands/storage/detach.js +2 -1
- package/dist/commands/storage/detach.js.map +1 -1
- package/dist/commands/storage/list.d.ts +1 -0
- package/dist/commands/storage/list.js +7 -2
- package/dist/commands/storage/list.js.map +1 -1
- package/dist/commands/storage/order.d.ts +3 -0
- package/dist/commands/storage/order.js +101 -18
- package/dist/commands/storage/order.js.map +1 -1
- package/dist/commands/storage/resize.d.ts +1 -0
- package/dist/commands/storage/resize.js +20 -6
- package/dist/commands/storage/resize.js.map +1 -1
- package/dist/commands/team/details.d.ts +1 -0
- package/dist/commands/team/details.js +1 -0
- package/dist/commands/team/details.js.map +1 -1
- package/dist/commands/team/invite.d.ts +1 -0
- package/dist/commands/team/invite.js +1 -0
- package/dist/commands/team/invite.js.map +1 -1
- package/dist/commands/team.d.ts +1 -0
- package/dist/commands/team.js +1 -0
- package/dist/commands/team.js.map +1 -1
- package/dist/commands/tickets/close.d.ts +1 -0
- package/dist/commands/tickets/close.js +1 -0
- package/dist/commands/tickets/close.js.map +1 -1
- package/dist/commands/tickets/create.d.ts +3 -0
- package/dist/commands/tickets/create.js +41 -1
- package/dist/commands/tickets/create.js.map +1 -1
- package/dist/commands/tickets/departments.d.ts +1 -0
- package/dist/commands/tickets/departments.js +1 -0
- package/dist/commands/tickets/departments.js.map +1 -1
- package/dist/commands/tickets/download.d.ts +18 -0
- package/dist/commands/tickets/download.js +138 -0
- package/dist/commands/tickets/download.js.map +1 -0
- package/dist/commands/tickets/list.d.ts +1 -0
- package/dist/commands/tickets/list.js +14 -7
- package/dist/commands/tickets/list.js.map +1 -1
- package/dist/commands/tickets/open.d.ts +1 -0
- package/dist/commands/tickets/open.js +1 -0
- package/dist/commands/tickets/open.js.map +1 -1
- package/dist/commands/tickets/reopen.d.ts +11 -0
- package/dist/commands/tickets/reopen.js +34 -0
- package/dist/commands/tickets/reopen.js.map +1 -0
- package/dist/commands/tickets/reply.d.ts +3 -0
- package/dist/commands/tickets/reply.js +34 -4
- package/dist/commands/tickets/reply.js.map +1 -1
- package/dist/commands/transit.d.ts +1 -0
- package/dist/commands/transit.js +1 -0
- package/dist/commands/transit.js.map +1 -1
- package/dist/commands/tui/index.d.ts +1 -0
- package/dist/commands/tui/index.js +21 -0
- package/dist/commands/tui/index.js.map +1 -1
- package/dist/commands/vds/activity.d.ts +1 -0
- package/dist/commands/vds/activity.js +1 -0
- package/dist/commands/vds/activity.js.map +1 -1
- package/dist/commands/vds/bandwidth.d.ts +1 -0
- package/dist/commands/vds/bandwidth.js +1 -0
- package/dist/commands/vds/bandwidth.js.map +1 -1
- package/dist/commands/vds/boot-order.d.ts +1 -0
- package/dist/commands/vds/boot-order.js +1 -0
- package/dist/commands/vds/boot-order.js.map +1 -1
- package/dist/commands/vds/console.d.ts +1 -0
- package/dist/commands/vds/console.js +1 -0
- package/dist/commands/vds/console.js.map +1 -1
- package/dist/commands/vds/details.d.ts +1 -0
- package/dist/commands/vds/details.js +1 -0
- package/dist/commands/vds/details.js.map +1 -1
- package/dist/commands/vds/index.d.ts +1 -0
- package/dist/commands/vds/index.js +1 -0
- package/dist/commands/vds/index.js.map +1 -1
- package/dist/commands/vds/ip/add.d.ts +1 -0
- package/dist/commands/vds/ip/add.js +1 -0
- package/dist/commands/vds/ip/add.js.map +1 -1
- package/dist/commands/vds/ip/list.d.ts +1 -0
- package/dist/commands/vds/ip/list.js +1 -0
- package/dist/commands/vds/ip/list.js.map +1 -1
- package/dist/commands/vds/list.d.ts +1 -0
- package/dist/commands/vds/list.js +1 -0
- package/dist/commands/vds/list.js.map +1 -1
- package/dist/commands/vds/order.d.ts +1 -0
- package/dist/commands/vds/order.js +73 -7
- package/dist/commands/vds/order.js.map +1 -1
- package/dist/commands/vds/power.d.ts +1 -0
- package/dist/commands/vds/power.js +1 -0
- package/dist/commands/vds/power.js.map +1 -1
- package/dist/commands/vds/reinstall.d.ts +1 -0
- package/dist/commands/vds/reinstall.js +1 -0
- package/dist/commands/vds/reinstall.js.map +1 -1
- package/dist/commands/vds/resize.d.ts +1 -0
- package/dist/commands/vds/resize.js +1 -0
- package/dist/commands/vds/resize.js.map +1 -1
- package/dist/commands/vds/stats.d.ts +1 -0
- package/dist/commands/vds/stats.js +1 -0
- package/dist/commands/vds/stats.js.map +1 -1
- package/dist/commands/vps/activity.d.ts +1 -0
- package/dist/commands/vps/activity.js +1 -0
- package/dist/commands/vps/activity.js.map +1 -1
- package/dist/commands/vps/bandwidth.d.ts +1 -0
- package/dist/commands/vps/bandwidth.js +1 -0
- package/dist/commands/vps/bandwidth.js.map +1 -1
- package/dist/commands/vps/boot-order.d.ts +1 -0
- package/dist/commands/vps/boot-order.js +1 -0
- package/dist/commands/vps/boot-order.js.map +1 -1
- package/dist/commands/vps/console.d.ts +1 -0
- package/dist/commands/vps/console.js +15 -6
- package/dist/commands/vps/console.js.map +1 -1
- package/dist/commands/vps/details.d.ts +1 -0
- package/dist/commands/vps/details.js +8 -1
- package/dist/commands/vps/details.js.map +1 -1
- package/dist/commands/vps/ip/add.d.ts +1 -0
- package/dist/commands/vps/ip/add.js +77 -9
- package/dist/commands/vps/ip/add.js.map +1 -1
- package/dist/commands/vps/ip/list.d.ts +1 -0
- package/dist/commands/vps/ip/list.js +1 -0
- package/dist/commands/vps/ip/list.js.map +1 -1
- package/dist/commands/vps/list.d.ts +1 -0
- package/dist/commands/vps/list.js +14 -4
- package/dist/commands/vps/list.js.map +1 -1
- package/dist/commands/vps/order.d.ts +20 -0
- package/dist/commands/vps/order.js +180 -23
- package/dist/commands/vps/order.js.map +1 -1
- package/dist/commands/vps/power.d.ts +1 -0
- package/dist/commands/vps/power.js +3 -2
- package/dist/commands/vps/power.js.map +1 -1
- package/dist/commands/vps/reinstall.d.ts +1 -0
- package/dist/commands/vps/reinstall.js +3 -2
- package/dist/commands/vps/reinstall.js.map +1 -1
- package/dist/commands/vps/resize.d.ts +1 -0
- package/dist/commands/vps/resize.js +37 -13
- package/dist/commands/vps/resize.js.map +1 -1
- package/dist/commands/vps/stats.d.ts +1 -0
- package/dist/commands/vps/stats.js +1 -0
- package/dist/commands/vps/stats.js.map +1 -1
- package/dist/commands/whoami.d.ts +6 -0
- package/dist/commands/whoami.js +8 -2
- package/dist/commands/whoami.js.map +1 -1
- package/dist/config/paths.d.ts +1 -1
- package/dist/config/paths.js +6 -1
- package/dist/config/paths.js.map +1 -1
- package/dist/config/store.d.ts +58 -0
- package/dist/config/store.js +84 -2
- package/dist/config/store.js.map +1 -1
- package/dist/functions-support/credits.d.ts +64 -0
- package/dist/functions-support/credits.js +181 -0
- package/dist/functions-support/credits.js.map +1 -0
- package/dist/functions-support/cron.d.ts +17 -0
- package/dist/functions-support/cron.js +99 -0
- package/dist/functions-support/cron.js.map +1 -0
- package/dist/functions-support/env.d.ts +23 -0
- package/dist/functions-support/env.js +44 -0
- package/dist/functions-support/env.js.map +1 -0
- package/dist/functions-support/link.d.ts +25 -0
- package/dist/functions-support/link.js +51 -0
- package/dist/functions-support/link.js.map +1 -0
- package/dist/functions-support/poll.d.ts +40 -0
- package/dist/functions-support/poll.js +109 -0
- package/dist/functions-support/poll.js.map +1 -0
- package/dist/functions-support/resolve.d.ts +3 -0
- package/dist/functions-support/resolve.js +31 -0
- package/dist/functions-support/resolve.js.map +1 -0
- package/dist/functions-support/runtime.d.ts +30 -0
- package/dist/functions-support/runtime.js +52 -0
- package/dist/functions-support/runtime.js.map +1 -0
- package/dist/functions-support/source.d.ts +92 -0
- package/dist/functions-support/source.js +343 -0
- package/dist/functions-support/source.js.map +1 -0
- package/dist/help/help-filter.d.ts +10 -0
- package/dist/help/help-filter.js +9 -0
- package/dist/help/help-filter.js.map +1 -0
- package/dist/help/scope-aware-help.d.ts +30 -0
- package/dist/help/scope-aware-help.js +80 -0
- package/dist/help/scope-aware-help.js.map +1 -0
- package/dist/tui/App.js +11 -26
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/Menu.d.ts +3 -1
- package/dist/tui/components/Menu.js +7 -3
- package/dist/tui/components/Menu.js.map +1 -1
- package/dist/tui/components/NumberInput.js +1 -1
- package/dist/tui/components/Sparkline.js +1 -1
- package/dist/tui/router.d.ts +1 -1
- package/dist/tui/router.js.map +1 -1
- package/dist/tui/screens/Billing.js +66 -14
- package/dist/tui/screens/Billing.js.map +1 -1
- package/dist/tui/screens/Dashboard.js +8 -7
- package/dist/tui/screens/Dashboard.js.map +1 -1
- package/dist/tui/screens/Deploy.d.ts +2 -0
- package/dist/tui/screens/Deploy.js +912 -0
- package/dist/tui/screens/Deploy.js.map +1 -0
- package/dist/tui/screens/Order.js +385 -52
- package/dist/tui/screens/Order.js.map +1 -1
- package/dist/tui/screens/Resources.js +277 -35
- package/dist/tui/screens/Resources.js.map +1 -1
- package/dist/tui/screens/Tickets.js +47 -26
- package/dist/tui/screens/Tickets.js.map +1 -1
- package/dist/tui/screens/deployPreset.d.ts +20 -0
- package/dist/tui/screens/deployPreset.js +11 -0
- package/dist/tui/screens/deployPreset.js.map +1 -0
- package/dist/tui/screens/resources/AppDetail.d.ts +7 -0
- package/dist/tui/screens/resources/AppDetail.js +810 -0
- package/dist/tui/screens/resources/AppDetail.js.map +1 -0
- package/dist/tui/screens/resources/FunctionDetail.d.ts +7 -0
- package/dist/tui/screens/resources/FunctionDetail.js +751 -0
- package/dist/tui/screens/resources/FunctionDetail.js.map +1 -0
- package/dist/ui/attach.d.ts +15 -0
- package/dist/ui/attach.js +63 -0
- package/dist/ui/attach.js.map +1 -0
- package/dist/ui/baremetal-resolve.d.ts +10 -0
- package/dist/ui/baremetal-resolve.js +50 -0
- package/dist/ui/baremetal-resolve.js.map +1 -0
- package/dist/ui/confirm.js +1 -1
- package/dist/ui/confirm.js.map +1 -1
- package/dist/ui/cycle.d.ts +66 -0
- package/dist/ui/cycle.js +96 -0
- package/dist/ui/cycle.js.map +1 -0
- package/dist/ui/deploy-ui.d.ts +75 -0
- package/dist/ui/deploy-ui.js +243 -0
- package/dist/ui/deploy-ui.js.map +1 -0
- package/dist/ui/order-result.d.ts +4 -0
- package/dist/ui/order-result.js +32 -0
- package/dist/ui/order-result.js.map +1 -0
- package/dist/ui/payment-gate.d.ts +26 -0
- package/dist/ui/payment-gate.js +70 -0
- package/dist/ui/payment-gate.js.map +1 -0
- package/dist/ui/payment.js +10 -3
- package/dist/ui/payment.js.map +1 -1
- package/dist/ui/portal.d.ts +1 -1
- package/dist/ui/portal.js +7 -2
- package/dist/ui/portal.js.map +1 -1
- package/dist/ui/project-resolve.d.ts +25 -0
- package/dist/ui/project-resolve.js +31 -0
- package/dist/ui/project-resolve.js.map +1 -0
- package/dist/ui/render-mode.d.ts +5 -0
- package/dist/ui/render-mode.js +1 -1
- package/dist/ui/render-mode.js.map +1 -1
- package/dist/ui/resource-detail.js +0 -3
- package/dist/ui/resource-detail.js.map +1 -1
- package/dist/ui/resource-resolve.d.ts +9 -2
- package/dist/ui/resource-resolve.js +11 -4
- package/dist/ui/resource-resolve.js.map +1 -1
- package/dist/ui/spinner.d.ts +10 -1
- package/dist/ui/spinner.js +12 -3
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/table.d.ts +7 -0
- package/dist/ui/table.js +11 -0
- package/dist/ui/table.js.map +1 -1
- package/dist/ui/tax.d.ts +10 -0
- package/dist/ui/tax.js +31 -0
- package/dist/ui/tax.js.map +1 -0
- package/dist/ui/ticket-resolve.d.ts +9 -1
- package/dist/ui/ticket-resolve.js +13 -2
- package/dist/ui/ticket-resolve.js.map +1 -1
- package/dist/ui/volume-resolve.js +4 -1
- package/dist/ui/volume-resolve.js.map +1 -1
- package/dist/ui/wait.d.ts +4 -0
- package/dist/ui/wait.js +7 -2
- package/dist/ui/wait.js.map +1 -1
- package/dist/ui/wizard.d.ts +2 -1
- package/dist/ui/wizard.js +1 -1
- package/dist/ui/wizard.js.map +1 -1
- package/dist/version-check-bin.d.ts +35 -0
- package/dist/version-check-bin.js +123 -0
- package/dist/version-check-bin.js.map +1 -0
- package/dist/version-check.d.ts +44 -0
- package/dist/version-check.js +153 -0
- package/dist/version-check.js.map +1 -0
- package/package.json +59 -4
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source deploy plumbing shared by `synteq deploy` and the TUI's Deploy
|
|
3
|
+
* walkthrough: pack a directory, pick the build frontend, and follow a
|
|
4
|
+
* build → release to its outcome. Lifted out of commands/deploy.ts so the
|
|
5
|
+
* two surfaces cannot drift (the same excludes, the same terminal states,
|
|
6
|
+
* the same "a succeeded build is not a live release" rule).
|
|
7
|
+
*/
|
|
8
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
9
|
+
import { mkdtempSync, statSync, lstatSync, existsSync, readdirSync, readFileSync, createReadStream, createWriteStream, rmSync, } from "node:fs";
|
|
10
|
+
import { readFile } from "node:fs/promises";
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
|
+
import { request as httpRequest } from "node:http";
|
|
13
|
+
import { request as httpsRequest } from "node:https";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
import { dirname, join } from "node:path";
|
|
16
|
+
import { Readable, Transform } from "node:stream";
|
|
17
|
+
import { pipeline } from "node:stream/promises";
|
|
18
|
+
import { ApiError, NetworkError } from "../api/errors.js";
|
|
19
|
+
import { isTransientError } from "../ui/wait.js";
|
|
20
|
+
/** Terminal build statuses — polling stops here. Mirrors the backend
|
|
21
|
+
* BuildStatus enum (pending | building | pushing | succeeded | failed). */
|
|
22
|
+
export const BUILD_TERMINAL = new Set(["succeeded", "failed"]);
|
|
23
|
+
/** Terminal release outcomes a deploy can end in. */
|
|
24
|
+
export const RELEASE_TERMINAL = new Set([
|
|
25
|
+
"live",
|
|
26
|
+
"start_failed",
|
|
27
|
+
"health_failed",
|
|
28
|
+
"superseded",
|
|
29
|
+
]);
|
|
30
|
+
/** An explicit choice wins; otherwise a Dockerfile in the source root means
|
|
31
|
+
* `dockerfile`, and its absence means `railpack` (zero-config). Without
|
|
32
|
+
* this a Dockerfile-less repo would fail with "open Dockerfile: no such
|
|
33
|
+
* file". */
|
|
34
|
+
export function pickFrontend(dir, explicit) {
|
|
35
|
+
if (explicit === "dockerfile" || explicit === "railpack")
|
|
36
|
+
return explicit;
|
|
37
|
+
return existsSync(join(dir, "Dockerfile")) ? "dockerfile" : "railpack";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Tarball a directory to a temp .tgz using the system `tar`. Excludes
|
|
41
|
+
* dependency caches and VCS metadata ONLY — they are never build inputs and
|
|
42
|
+
* dominate the archive. Build OUTPUT directories (`dist`, `.next`) are
|
|
43
|
+
* deliberately kept: a Go app embedding its prebuilt frontend needs them,
|
|
44
|
+
* and anchoring an exclude to the root is not portable across GNU tar and
|
|
45
|
+
* bsdtar. Resolves to the archive path.
|
|
46
|
+
*/
|
|
47
|
+
/** Never build inputs: dependency caches and VCS metadata. */
|
|
48
|
+
export const TARBALL_EXCLUDES = [".git", "node_modules", ".venv", "__pycache__"];
|
|
49
|
+
/** The `.env.*` spellings that document the variables an app wants, never
|
|
50
|
+
* their values: they ship like any other file. */
|
|
51
|
+
const DOTENV_DOC_SUFFIXES = [".example", ".sample", ".template"];
|
|
52
|
+
/**
|
|
53
|
+
* Is `name` (one path segment) a dotenv file: `.env` or `.env.<anything>`
|
|
54
|
+
* (`.env.local`, `.env.production`), but not `.env.example`, `.env.sample`
|
|
55
|
+
* or `.env.template`?
|
|
56
|
+
*
|
|
57
|
+
* A dotenv file holds the secrets of the machine you deploy FROM. It is never
|
|
58
|
+
* packed, on any intake path: the image goes to a registry and a `COPY . .`
|
|
59
|
+
* would bake it into every layer, so the orchestrator drops it at extraction
|
|
60
|
+
* too (apps `build.IsDotenvName`, the same rule). Variables for the deployed
|
|
61
|
+
* app are set with `synteq app env set` / `synteq function env set` or the
|
|
62
|
+
* Environment tab and injected at run time. There is no opt-in: `tar` has no
|
|
63
|
+
* negation, and a `!.env` line in `.synteqignore` is not honoured.
|
|
64
|
+
*/
|
|
65
|
+
export function isDotenvName(name) {
|
|
66
|
+
if (name === ".env")
|
|
67
|
+
return true;
|
|
68
|
+
if (!name.startsWith(".env."))
|
|
69
|
+
return false;
|
|
70
|
+
return !DOTENV_DOC_SUFFIXES.some((s) => name.endsWith(s));
|
|
71
|
+
}
|
|
72
|
+
/** Does any segment of a slash-separated relative path name a dotenv file? */
|
|
73
|
+
export function hasDotenvSegment(relPath) {
|
|
74
|
+
return relPath.split("/").some(isDotenvName);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The dotenv files `makeTarball` leaves out of `dir`, as root-relative
|
|
78
|
+
* paths: what git lists for a checkout, else a walk of the tree (skipping
|
|
79
|
+
* `TARBALL_EXCLUDES` and never following symlinks). Printed by the deploy so
|
|
80
|
+
* nobody wonders where their `.env` went.
|
|
81
|
+
*/
|
|
82
|
+
export function dotenvFiles(dir) {
|
|
83
|
+
const files = gitSourceListRaw(dir);
|
|
84
|
+
if (files !== null)
|
|
85
|
+
return files.filter(hasDotenvSegment).sort();
|
|
86
|
+
const found = [];
|
|
87
|
+
const walk = (abs, rel) => {
|
|
88
|
+
let entries;
|
|
89
|
+
try {
|
|
90
|
+
entries = readdirSync(abs);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
for (const name of entries.sort()) {
|
|
96
|
+
if (TARBALL_EXCLUDES.includes(name))
|
|
97
|
+
continue;
|
|
98
|
+
const relPath = rel ? `${rel}/${name}` : name;
|
|
99
|
+
let st;
|
|
100
|
+
try {
|
|
101
|
+
st = lstatSync(join(abs, name));
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (st.isSymbolicLink())
|
|
107
|
+
continue;
|
|
108
|
+
if (isDotenvName(name)) {
|
|
109
|
+
found.push(relPath);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (st.isDirectory())
|
|
113
|
+
walk(join(abs, name), relPath);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
walk(dir, "");
|
|
117
|
+
return found;
|
|
118
|
+
}
|
|
119
|
+
/** Build OUTPUT that can legitimately be shipped (a prebuilt frontend) but
|
|
120
|
+
* never counts as "source" on its own — a checkout with nothing else left
|
|
121
|
+
* in it (a branch switch that removed the tracked files, a wrong cwd) is
|
|
122
|
+
* exactly the upload that fails late in the builder with a bare "could not
|
|
123
|
+
* determine how to build the app". */
|
|
124
|
+
const OUTPUT_ONLY_DIRS = new Set(["dist", "build", "out", ".next", ".nuxt", "target", ".output", "coverage"]);
|
|
125
|
+
/**
|
|
126
|
+
* The names at the root of what `makeTarball` would ship that are actual
|
|
127
|
+
* source: anything that is not an excluded cache, not build output, and not
|
|
128
|
+
* OS/editor noise. Empty means there is nothing for a builder to work from.
|
|
129
|
+
*/
|
|
130
|
+
export function sourceRootEntries(dir) {
|
|
131
|
+
return readdirSync(dir).filter((name) => !TARBALL_EXCLUDES.includes(name) &&
|
|
132
|
+
!OUTPUT_ONLY_DIRS.has(name) &&
|
|
133
|
+
!isDotenvName(name) &&
|
|
134
|
+
name !== ".DS_Store" &&
|
|
135
|
+
!name.startsWith("._"));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The file list `makeTarball` ships when `dir` is a git checkout: what git
|
|
139
|
+
* itself considers tracked or untracked-but-not-ignored, so `.gitignore` is
|
|
140
|
+
* honoured exactly and build output such as `.next`, `.open-next` or
|
|
141
|
+
* `.wrangler` never ships (the 471 MB marketing-site pack, 2026-09-27). Null
|
|
142
|
+
* when `dir` is not a git checkout or git is unavailable; the caller then
|
|
143
|
+
* falls back to the static excludes plus `.synteqignore`. Paths are relative
|
|
144
|
+
* to `dir`. Dotenv files (`isDotenvName`) are left out even when git tracks
|
|
145
|
+
* them.
|
|
146
|
+
*/
|
|
147
|
+
export function gitSourceList(dir) {
|
|
148
|
+
return gitSourceListRaw(dir)?.filter((f) => !hasDotenvSegment(f)) ?? null;
|
|
149
|
+
}
|
|
150
|
+
/** `gitSourceList` before the dotenv rule: what git says is source. */
|
|
151
|
+
function gitSourceListRaw(dir) {
|
|
152
|
+
const probe = spawnSync("git", ["-C", dir, "rev-parse", "--is-inside-work-tree"], { encoding: "utf8" });
|
|
153
|
+
if (probe.status !== 0 || probe.stdout.trim() !== "true")
|
|
154
|
+
return null;
|
|
155
|
+
const ls = spawnSync("git", ["-C", dir, "ls-files", "--cached", "--others", "--exclude-standard", "-z"], { encoding: "utf8", maxBuffer: 256 * 1024 * 1024 });
|
|
156
|
+
if (ls.status !== 0)
|
|
157
|
+
return null;
|
|
158
|
+
const excluded = new Set(TARBALL_EXCLUDES);
|
|
159
|
+
return ls.stdout
|
|
160
|
+
.split("\0")
|
|
161
|
+
.filter((f) => f.length > 0)
|
|
162
|
+
.filter((f) => !f.split("/").some((seg) => excluded.has(seg)))
|
|
163
|
+
.filter((f) => existsSync(join(dir, f)));
|
|
164
|
+
}
|
|
165
|
+
/** Extra `--exclude` patterns from a `.synteqignore` in `dir` (one per line,
|
|
166
|
+
* `#` comments) for folders that are not git checkouts. */
|
|
167
|
+
export function synteqIgnorePatterns(dir) {
|
|
168
|
+
const f = join(dir, ".synteqignore");
|
|
169
|
+
if (!existsSync(f))
|
|
170
|
+
return [];
|
|
171
|
+
return readFileSync(f, "utf8")
|
|
172
|
+
.split("\n")
|
|
173
|
+
.map((l) => l.trim())
|
|
174
|
+
.filter((l) => l && !l.startsWith("#"));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Download a source tarball to a temp file — `synteq deploy --source-url`.
|
|
178
|
+
* The CLI fetches it and uploads it the way a packed directory goes up: the
|
|
179
|
+
* platform never dials a customer-supplied URL. Returns the file's path; the
|
|
180
|
+
* caller removes its directory, as with makeTarball.
|
|
181
|
+
*
|
|
182
|
+
* Errors name the host only: a pre-signed URL is a credential.
|
|
183
|
+
*/
|
|
184
|
+
export async function fetchSourceTarball(rawUrl, opts = {}) {
|
|
185
|
+
let url;
|
|
186
|
+
try {
|
|
187
|
+
url = new URL(rawUrl);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
throw new Error("--source-url is not a valid URL.");
|
|
191
|
+
}
|
|
192
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
193
|
+
throw new Error("--source-url must be an http(s) URL.");
|
|
194
|
+
}
|
|
195
|
+
let res;
|
|
196
|
+
try {
|
|
197
|
+
res = await (opts.fetchFn ?? fetch)(url, { redirect: "follow" });
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
throw new Error(`Could not reach ${url.host} to download the source tarball.`);
|
|
201
|
+
}
|
|
202
|
+
if (!res.ok || !res.body) {
|
|
203
|
+
throw new Error(`${url.host} answered ${res.status} for the source tarball.`);
|
|
204
|
+
}
|
|
205
|
+
const tooLarge = () => new Error(`The source tarball is larger than your plan's ${Math.floor((opts.maxBytes ?? 0) / 1_000_000)} MB source limit.`);
|
|
206
|
+
const announced = Number(res.headers.get("content-length") ?? 0);
|
|
207
|
+
if (opts.maxBytes && announced > opts.maxBytes)
|
|
208
|
+
throw tooLarge();
|
|
209
|
+
const out = join(mkdtempSync(join(tmpdir(), "synteq-deploy-")), "source.tgz");
|
|
210
|
+
let head = Buffer.alloc(0);
|
|
211
|
+
let size = 0;
|
|
212
|
+
const meter = new Transform({
|
|
213
|
+
transform(chunk, _enc, cb) {
|
|
214
|
+
size += chunk.length;
|
|
215
|
+
if (head.length < 2)
|
|
216
|
+
head = Buffer.concat([head, chunk]).subarray(0, 2);
|
|
217
|
+
cb(opts.maxBytes && size > opts.maxBytes ? tooLarge() : null, chunk);
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
try {
|
|
221
|
+
await pipeline(Readable.fromWeb(res.body), meter, createWriteStream(out));
|
|
222
|
+
if (head.length < 2 || head[0] !== 0x1f || head[1] !== 0x8b) {
|
|
223
|
+
throw new Error(`${url.host} did not return a gzip tarball (.tar.gz / .tgz).`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
rmSync(dirname(out), { recursive: true, force: true });
|
|
228
|
+
if (e instanceof Error && /source (tarball|limit)|gzip tarball/.test(e.message))
|
|
229
|
+
throw e;
|
|
230
|
+
throw new Error(`The download from ${url.host} was interrupted.`);
|
|
231
|
+
}
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
export function makeTarball(dir) {
|
|
235
|
+
const out = join(mkdtempSync(join(tmpdir(), "synteq-deploy-")), "source.tgz");
|
|
236
|
+
const files = gitSourceList(dir);
|
|
237
|
+
let args;
|
|
238
|
+
let stdinList = null;
|
|
239
|
+
if (files !== null) {
|
|
240
|
+
// git decides what is source: tracked + untracked-not-ignored files.
|
|
241
|
+
args = ["-czf", out, "-C", dir, "--null", "-T", "-"];
|
|
242
|
+
stdinList = files.map((f) => `./${f}`).join("\0") + (files.length ? "\0" : "");
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// Dotenv files go in by the basenames actually present (`.env`,
|
|
246
|
+
// `.env.local`...): a basename `--exclude` matches at any depth on both
|
|
247
|
+
// GNU tar and bsdtar, and naming only the files found keeps
|
|
248
|
+
// `.env.example` — tar has no way to say `.env.*` minus the docs.
|
|
249
|
+
const dotenv = [...new Set(dotenvFiles(dir).map((f) => f.slice(f.lastIndexOf("/") + 1)))];
|
|
250
|
+
const excludes = [...TARBALL_EXCLUDES, ...dotenv, ...synteqIgnorePatterns(dir)];
|
|
251
|
+
args = ["-czf", out, ...excludes.flatMap((e) => ["--exclude", e]), "-C", dir, "."];
|
|
252
|
+
}
|
|
253
|
+
return new Promise((res, rej) => {
|
|
254
|
+
// COPYFILE_DISABLE: macOS bsdtar otherwise writes AppleDouble `._name`
|
|
255
|
+
// entries next to every file with extended attributes, which the builder
|
|
256
|
+
// then lists as if they were source.
|
|
257
|
+
const p = spawn("tar", args, {
|
|
258
|
+
stdio: [stdinList === null ? "ignore" : "pipe", "ignore", "pipe"],
|
|
259
|
+
env: { ...process.env, COPYFILE_DISABLE: "1" },
|
|
260
|
+
});
|
|
261
|
+
if (stdinList !== null && p.stdin)
|
|
262
|
+
p.stdin.end(stdinList);
|
|
263
|
+
let stderr = "";
|
|
264
|
+
p.stderr?.on("data", (d) => (stderr += d.toString()));
|
|
265
|
+
p.on("error", (e) => rej(new Error(`Could not run tar (${e.message}). Is tar installed?`)));
|
|
266
|
+
p.on("close", (code) => code === 0 ? res(out) : rej(new Error(`tar exited ${code}: ${stderr.trim() || "unknown error"}`)));
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
export function humanSize(path) {
|
|
270
|
+
try {
|
|
271
|
+
const bytes = statSync(path).size;
|
|
272
|
+
if (bytes < 1024)
|
|
273
|
+
return `${bytes} B`;
|
|
274
|
+
if (bytes < 1024 * 1024)
|
|
275
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
276
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return "?";
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
export function sleep(ms) {
|
|
283
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
284
|
+
}
|
|
285
|
+
// ── Direct source upload (task P3) ──────────────────────────────────────
|
|
286
|
+
//
|
|
287
|
+
// `synteq deploy --dir` used to send the whole tarball as the raw body of
|
|
288
|
+
// POST /apps/{id}/deploys/source. A proxy in front of the API rejects
|
|
289
|
+
// bodies over 100 MB, and the archive can legitimately be ~1 GB, so the
|
|
290
|
+
// direct path instead PUTs the file straight to the object store via a
|
|
291
|
+
// presigned URL the API mints, then tells the API which object to build
|
|
292
|
+
// from. `uploadSource()` is the one entry point both `commands/deploy.ts`
|
|
293
|
+
// and `tui/screens/Deploy.tsx` call, so the two surfaces can't diverge on
|
|
294
|
+
// retry/fallback behaviour.
|
|
295
|
+
/** Packed-source cap the CLI falls back to the raw-body upload under, when
|
|
296
|
+
* the cluster doesn't support direct upload at all (D6 in the design doc). */
|
|
297
|
+
export const RAW_FALLBACK_MAX_BYTES = 95_000_000;
|
|
298
|
+
const UPLOAD_MAX_ATTEMPTS = 3;
|
|
299
|
+
const UPLOAD_BACKOFF_MS = [1000, 3000];
|
|
300
|
+
/** Thrown by `putFile` for a non-2xx response from the upload host, so
|
|
301
|
+
* `uploadSource` can tell a signature/size mismatch (403 — do not retry)
|
|
302
|
+
* apart from a transient 5xx (retry with a fresh URL) without parsing
|
|
303
|
+
* strings. */
|
|
304
|
+
export class UploadPutError extends Error {
|
|
305
|
+
status;
|
|
306
|
+
constructor(status, message) {
|
|
307
|
+
super(message);
|
|
308
|
+
this.status = status;
|
|
309
|
+
this.name = "UploadPutError";
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* SHA-256 of a file, streamed — never loads the file into memory. The
|
|
314
|
+
* archive can be ~1 GB; `crypto.createHash` over `fs.createReadStream` is
|
|
315
|
+
* the only way to hash that without a huge Buffer.
|
|
316
|
+
*/
|
|
317
|
+
export function sha256File(path) {
|
|
318
|
+
return new Promise((resolvePromise, reject) => {
|
|
319
|
+
const hash = createHash("sha256");
|
|
320
|
+
const stream = createReadStream(path);
|
|
321
|
+
stream.on("error", reject);
|
|
322
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
323
|
+
stream.on("end", () => resolvePromise(hash.digest("hex")));
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* PUT a file's exact bytes to a presigned URL, streamed (never buffers the
|
|
328
|
+
* whole file). Uses `node:http`/`node:https` directly rather than `fetch`
|
|
329
|
+
* with a stream body: a streamed fetch body can fall back to chunked
|
|
330
|
+
* transfer-encoding instead of sending an explicit `Content-Length`, and the
|
|
331
|
+
* signed URL's signature covers `Content-Length` — a request that arrives
|
|
332
|
+
* chunked (or with any other length) is refused with 403. `http.request`
|
|
333
|
+
* with the header set explicitly always sends exactly that Content-Length
|
|
334
|
+
* and never adds Transfer-Encoding (verified against a local test server —
|
|
335
|
+
* see test/apps-support/upload.test.ts).
|
|
336
|
+
*
|
|
337
|
+
* Sends no `Authorization` header — the URL itself is the credential, and
|
|
338
|
+
* the caller's bearer token/API key must never reach the object-store host.
|
|
339
|
+
* Resolves on 2xx; rejects with `UploadPutError` (carrying the status) on
|
|
340
|
+
* any other response, or with the underlying error for a network failure.
|
|
341
|
+
*
|
|
342
|
+
* Settles EXACTLY ONCE no matter how the connection ends: a clean 2xx/non-2xx
|
|
343
|
+
* response, a request-level error, a response-level error/abort, the
|
|
344
|
+
* underlying connection closing before a response ever completed (I-2 — a
|
|
345
|
+
* server that sends headers and part of a body, then drops the socket, used
|
|
346
|
+
* to leave this promise unsettled forever), or a 300s stall with no response
|
|
347
|
+
* (`req.setTimeout`, matching the platform's own idle timeout). The file read
|
|
348
|
+
* stream is destroyed whenever the request settles, whichever way.
|
|
349
|
+
*/
|
|
350
|
+
export function putFile(url, path, size, headers, onProgress, opts = {}) {
|
|
351
|
+
return new Promise((resolvePromise, reject) => {
|
|
352
|
+
let target;
|
|
353
|
+
try {
|
|
354
|
+
target = new URL(url);
|
|
355
|
+
}
|
|
356
|
+
catch (e) {
|
|
357
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const isHttps = target.protocol === "https:";
|
|
361
|
+
const doRequest = opts.requestFn ?? (isHttps ? httpsRequest : httpRequest);
|
|
362
|
+
// The signed URL's signature covers Content-Length; make sure OUR value
|
|
363
|
+
// wins and nothing upstream can sneak in a Transfer-Encoding instead.
|
|
364
|
+
const reqHeaders = { ...headers };
|
|
365
|
+
for (const k of Object.keys(reqHeaders)) {
|
|
366
|
+
if (k.toLowerCase() === "transfer-encoding")
|
|
367
|
+
delete reqHeaders[k];
|
|
368
|
+
}
|
|
369
|
+
reqHeaders["Content-Length"] = String(size);
|
|
370
|
+
const reqOptions = { method: "PUT", headers: reqHeaders };
|
|
371
|
+
if (isHttps && opts.insecure)
|
|
372
|
+
reqOptions.rejectUnauthorized = false;
|
|
373
|
+
let settled = false;
|
|
374
|
+
const stream = createReadStream(path);
|
|
375
|
+
const finish = (err) => {
|
|
376
|
+
if (settled)
|
|
377
|
+
return;
|
|
378
|
+
settled = true;
|
|
379
|
+
stream.destroy();
|
|
380
|
+
if (err)
|
|
381
|
+
reject(err);
|
|
382
|
+
else
|
|
383
|
+
resolvePromise();
|
|
384
|
+
};
|
|
385
|
+
const req = doRequest(target, reqOptions, (res) => {
|
|
386
|
+
let body = "";
|
|
387
|
+
res.setEncoding("utf8");
|
|
388
|
+
res.on("data", (chunk) => {
|
|
389
|
+
body += chunk;
|
|
390
|
+
});
|
|
391
|
+
res.on("end", () => {
|
|
392
|
+
const status = res.statusCode ?? 0;
|
|
393
|
+
if (status >= 200 && status < 300) {
|
|
394
|
+
finish();
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
finish(new UploadPutError(status, `Upload PUT failed with HTTP ${status}${body ? `: ${body.slice(0, 300)}` : ""}`));
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
// A connection that dies mid-response (after headers, before `end`)
|
|
401
|
+
// used to leave the promise unsettled forever — I-2.
|
|
402
|
+
res.on("error", (e) => finish(e instanceof Error ? e : new Error(String(e))));
|
|
403
|
+
res.on("aborted", () => finish(new Error("Upload response aborted before it finished.")));
|
|
404
|
+
});
|
|
405
|
+
// Matches the platform's own 300s idle timeout on this link — a stalled
|
|
406
|
+
// upload (no response, connection never closes) settles rather than
|
|
407
|
+
// hanging the command forever.
|
|
408
|
+
req.setTimeout(300_000, () => {
|
|
409
|
+
req.destroy(new Error("upload stalled"));
|
|
410
|
+
});
|
|
411
|
+
req.on("error", (e) => finish(e));
|
|
412
|
+
// The connection closing without a completed response (no `end`, no
|
|
413
|
+
// `error`) is the other half of I-2 — `finish`'s guard makes this a
|
|
414
|
+
// no-op on the normal path, where `end`/`error` already settled first.
|
|
415
|
+
req.on("close", () => finish(new Error("Upload connection closed before a response was received.")));
|
|
416
|
+
let sent = 0;
|
|
417
|
+
stream.on("error", (e) => {
|
|
418
|
+
req.destroy();
|
|
419
|
+
finish(e);
|
|
420
|
+
});
|
|
421
|
+
stream.on("data", (chunk) => {
|
|
422
|
+
sent += chunk.length;
|
|
423
|
+
onProgress?.(sent, size);
|
|
424
|
+
});
|
|
425
|
+
stream.pipe(req);
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Upload a packed source archive and trigger the build — the one path both
|
|
430
|
+
* `synteq deploy --dir` and the TUI's Deploy walkthrough call.
|
|
431
|
+
*
|
|
432
|
+
* Tries direct upload first: mint a presigned PUT (fresh on every attempt —
|
|
433
|
+
* a used or expired URL must not be reused; a retry's mint names the
|
|
434
|
+
* previous attempt's object key as `replaces`), stream the file to it, then
|
|
435
|
+
* tell the API which object to build. Up to 3 attempts total; a network
|
|
436
|
+
* error or a 5xx from the upload host retries (1s, then 3s backoff) with a
|
|
437
|
+
* brand-new URL; a 403 (signature/size mismatch) is reported immediately,
|
|
438
|
+
* never retried, since retrying with the same bytes would fail identically.
|
|
439
|
+
*
|
|
440
|
+
* Falls back to the existing raw-body upload (`apps.deploySource`, which
|
|
441
|
+
* buffers the whole tarball) when the API's upload-url endpoint answers
|
|
442
|
+
* 501/404/405 — an older server, or a cluster that doesn't support direct
|
|
443
|
+
* upload at all — and the pack is small enough for the proxy's 100 MB body
|
|
444
|
+
* limit (95 MB budget, D6). Otherwise fails with exit 1 (thrown Error) and
|
|
445
|
+
* says so.
|
|
446
|
+
*/
|
|
447
|
+
export async function uploadSource(api, appId, archivePath, opts = {}) {
|
|
448
|
+
const size = statSync(archivePath).size;
|
|
449
|
+
const sha256 = await sha256File(archivePath);
|
|
450
|
+
const doSleep = opts.sleepFn ?? sleep;
|
|
451
|
+
// Each mint holds one of the user's few pending-upload slots on the API.
|
|
452
|
+
// A retry names the attempt it replaces so that slot is released first —
|
|
453
|
+
// otherwise one failed deploy (3 mints) fills them all. An older API
|
|
454
|
+
// rejects the unknown field with 422: mint once more without it, and stop
|
|
455
|
+
// sending it for the rest of this upload.
|
|
456
|
+
let previousKey;
|
|
457
|
+
let sendReplaces = true;
|
|
458
|
+
const mintUploadUrl = async () => {
|
|
459
|
+
const replaces = sendReplaces ? previousKey : undefined;
|
|
460
|
+
if (replaces === undefined)
|
|
461
|
+
return api.apps.sourceUploadUrl(appId, { sizeBytes: size, sha256 });
|
|
462
|
+
try {
|
|
463
|
+
return await api.apps.sourceUploadUrl(appId, { sizeBytes: size, sha256, replaces });
|
|
464
|
+
}
|
|
465
|
+
catch (e) {
|
|
466
|
+
if (!(e instanceof ApiError && e.status === 422))
|
|
467
|
+
throw e;
|
|
468
|
+
sendReplaces = false;
|
|
469
|
+
return api.apps.sourceUploadUrl(appId, { sizeBytes: size, sha256 });
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
for (let attempt = 0; attempt < UPLOAD_MAX_ATTEMPTS; attempt++) {
|
|
473
|
+
let mint;
|
|
474
|
+
try {
|
|
475
|
+
mint = await mintUploadUrl();
|
|
476
|
+
previousKey = mint.objectKey;
|
|
477
|
+
}
|
|
478
|
+
catch (e) {
|
|
479
|
+
// m-3: only an old orchestrator (no route at all) or a cluster that
|
|
480
|
+
// has switched direct upload off falls back to the raw body. A 404
|
|
481
|
+
// from `_load_owned_app` (the app itself is gone) shares the status
|
|
482
|
+
// code but carries FastAPI's real detail, never the generic
|
|
483
|
+
// route-missing "Not Found" — that case must surface as-is so a
|
|
484
|
+
// vanished app isn't reported as "direct upload not available".
|
|
485
|
+
if (e instanceof ApiError &&
|
|
486
|
+
(e.status === 501 || e.status === 405 || (e.status === 404 && e.detail === "Not Found"))) {
|
|
487
|
+
return fallbackToRawUpload(api, appId, archivePath, size);
|
|
488
|
+
}
|
|
489
|
+
if (e instanceof NetworkError && attempt < UPLOAD_MAX_ATTEMPTS - 1) {
|
|
490
|
+
await doSleep(UPLOAD_BACKOFF_MS[attempt] ?? 3000);
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
throw e;
|
|
494
|
+
}
|
|
495
|
+
let lastPercent = -1;
|
|
496
|
+
try {
|
|
497
|
+
await putFile(mint.uploadUrl, archivePath, size, mint.headers, (sentBytes, totalBytes) => {
|
|
498
|
+
// m-1: fire onProgress only when the integer percent changes — a
|
|
499
|
+
// raw per-chunk callback floods the TUI/spinner with ~16k updates
|
|
500
|
+
// for a 1 GB upload.
|
|
501
|
+
const pct = Math.floor((sentBytes / totalBytes) * 100);
|
|
502
|
+
if (pct !== lastPercent) {
|
|
503
|
+
lastPercent = pct;
|
|
504
|
+
opts.onProgress?.(pct);
|
|
505
|
+
}
|
|
506
|
+
}, { insecure: api.insecureTls });
|
|
507
|
+
}
|
|
508
|
+
catch (e) {
|
|
509
|
+
if (e instanceof UploadPutError) {
|
|
510
|
+
if (e.status === 403) {
|
|
511
|
+
throw new Error("Upload rejected (403) — the signed upload URL no longer matches this file. Re-run the deploy.");
|
|
512
|
+
}
|
|
513
|
+
if (e.status >= 500 && attempt < UPLOAD_MAX_ATTEMPTS - 1) {
|
|
514
|
+
await doSleep(UPLOAD_BACKOFF_MS[attempt] ?? 3000);
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
// m-2: retries exhausted (or a non-403 status that isn't retried at
|
|
518
|
+
// all) — surface as the CLI's NetworkError (no url: the upload host's
|
|
519
|
+
// URL/query/object key must never reach a message) so
|
|
520
|
+
// BaseCommand.fail() maps it to exit 3, matching the CLI's contract
|
|
521
|
+
// for a server/network fault. The synthetic cause below carries only
|
|
522
|
+
// the HTTP status, never `e.message` (which can hold up to 300 bytes
|
|
523
|
+
// of the object store's raw XML error body, itself carrying the
|
|
524
|
+
// object key).
|
|
525
|
+
throw new NetworkError(new Error(`Upload host returned HTTP ${e.status}.`));
|
|
526
|
+
}
|
|
527
|
+
// A network error talking to the upload host — same retry rule as a
|
|
528
|
+
// network error minting the URL. Once retries are exhausted, wrap the
|
|
529
|
+
// raw node error (ECONNREFUSED/ECONNRESET/etc — carries host:port at
|
|
530
|
+
// most, never a path or query) the same way, for the same exit code.
|
|
531
|
+
if (attempt < UPLOAD_MAX_ATTEMPTS - 1) {
|
|
532
|
+
await doSleep(UPLOAD_BACKOFF_MS[attempt] ?? 3000);
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
throw new NetworkError(e);
|
|
536
|
+
}
|
|
537
|
+
return api.apps.deploySourceObject(appId, mint.objectKey);
|
|
538
|
+
}
|
|
539
|
+
throw new NetworkError(new Error("Uploading the source failed after 3 attempts."));
|
|
540
|
+
}
|
|
541
|
+
async function fallbackToRawUpload(api, appId, archivePath, size) {
|
|
542
|
+
if (size > RAW_FALLBACK_MAX_BYTES) {
|
|
543
|
+
throw new Error(`Direct upload is not available on this cluster, and the packed source ` +
|
|
544
|
+
`(${(size / 1_000_000).toFixed(1)} MB) is over the ${RAW_FALLBACK_MAX_BYTES / 1_000_000} MB ` +
|
|
545
|
+
`limit without it. Reduce the archive size, or ask an operator to enable direct upload.`);
|
|
546
|
+
}
|
|
547
|
+
const tarball = await readFile(archivePath);
|
|
548
|
+
return api.apps.deploySource(appId, new Uint8Array(tarball));
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Poll GET /apps/{id}/builds until the build reaches a terminal status or
|
|
552
|
+
* the timeout elapses. `onStatus` fires on every observed transition — of
|
|
553
|
+
* the status, or of the queue position / build VM while the status holds
|
|
554
|
+
* (bpool1) — so a caller can drive a spinner or a checklist. Returns the
|
|
555
|
+
* final build row — the caller decides what "timed out while building"
|
|
556
|
+
* means.
|
|
557
|
+
*/
|
|
558
|
+
export async function pollBuild(api, appId, initial, opts) {
|
|
559
|
+
const deadline = Date.now() + opts.timeoutMs;
|
|
560
|
+
let current = initial;
|
|
561
|
+
opts.onStatus?.(current.status, current);
|
|
562
|
+
while (!BUILD_TERMINAL.has(current.status) && Date.now() < deadline) {
|
|
563
|
+
await sleep(opts.intervalMs);
|
|
564
|
+
try {
|
|
565
|
+
const builds = await api.apps.builds(appId);
|
|
566
|
+
const found = builds.find((b) => b.id === initial.id);
|
|
567
|
+
if (found && (found.status !== current.status || buildDetail(found) !== buildDetail(current))) {
|
|
568
|
+
opts.onStatus?.(found.status, found);
|
|
569
|
+
}
|
|
570
|
+
if (found)
|
|
571
|
+
current = found;
|
|
572
|
+
}
|
|
573
|
+
catch (e) {
|
|
574
|
+
// A dropped connection or a 5xx is worth polling through. An expired
|
|
575
|
+
// session (or any other 4xx) is not: it would be retried, silently,
|
|
576
|
+
// until the 30-minute deadline. Same classification as `waitFor`.
|
|
577
|
+
if (!isTransientError(e))
|
|
578
|
+
throw e;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return current;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* The detail line behind a build's status while it waits or runs (bpool1):
|
|
585
|
+
* "Queued — position 2 of 5" from the orchestrator's build queue. Null when
|
|
586
|
+
* there is nothing to add (which build VM runs it stays internal).
|
|
587
|
+
*/
|
|
588
|
+
export function buildDetail(b) {
|
|
589
|
+
if (b.status === "pending" && b.queuePosition && b.queueTotal) {
|
|
590
|
+
return `Queued — position ${b.queuePosition} of ${b.queueTotal}`;
|
|
591
|
+
}
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* After a successful build, the release it produced — matched by image
|
|
596
|
+
* digest, polled briefly because the status cron mints it a beat after the
|
|
597
|
+
* build flips to succeeded. Null when it has not appeared in time.
|
|
598
|
+
*/
|
|
599
|
+
export async function resolveNewRelease(api, appId, build) {
|
|
600
|
+
if (!build.imageDigest)
|
|
601
|
+
return null;
|
|
602
|
+
for (let i = 0; i < 6; i++) {
|
|
603
|
+
try {
|
|
604
|
+
const releases = await api.apps.releases(appId);
|
|
605
|
+
const match = releases.find((r) => r.imageDigest === build.imageDigest);
|
|
606
|
+
if (match)
|
|
607
|
+
return { number: match.number, id: match.id };
|
|
608
|
+
}
|
|
609
|
+
catch {
|
|
610
|
+
// transient — try again
|
|
611
|
+
}
|
|
612
|
+
await sleep(1500);
|
|
613
|
+
}
|
|
614
|
+
return null;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Wait for a release to reach a terminal outcome — live, start_failed,
|
|
618
|
+
* health_failed, superseded — or return null when the window runs out (still
|
|
619
|
+
* rolling). This is what stops a caller from declaring "Deployed" on a build
|
|
620
|
+
* whose release then fails its rollout.
|
|
621
|
+
*/
|
|
622
|
+
export async function waitForReleaseOutcome(api, appId, releaseNumber, timeoutSeconds, onTick) {
|
|
623
|
+
const deadline = Date.now() + timeoutSeconds * 1000;
|
|
624
|
+
while (Date.now() < deadline) {
|
|
625
|
+
try {
|
|
626
|
+
const releases = await api.apps.releases(appId);
|
|
627
|
+
const r = releases.find((x) => x.number === releaseNumber);
|
|
628
|
+
onTick?.(r?.status ?? null);
|
|
629
|
+
if (r && RELEASE_TERMINAL.has(r.status))
|
|
630
|
+
return r.status;
|
|
631
|
+
}
|
|
632
|
+
catch {
|
|
633
|
+
// transient — keep polling
|
|
634
|
+
}
|
|
635
|
+
await sleep(3000);
|
|
636
|
+
}
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
//# sourceMappingURL=deploy.js.map
|