@synteq/cli 0.2.0 → 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/dist/api/client.d.ts +362 -5
- package/dist/api/client.js +559 -44
- package/dist/api/client.js.map +1 -1
- package/dist/api/factory.js +5 -2
- package/dist/api/factory.js.map +1 -1
- package/dist/api/types.d.ts +892 -3
- 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.js +4 -0
- package/dist/auth/scope.js.map +1 -1
- 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 +35 -0
- package/dist/base/command.js +87 -4
- package/dist/base/command.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 +0 -1
- package/dist/commands/api.js +6 -5
- 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/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/show.js +4 -1
- package/dist/commands/config/show.js.map +1 -1
- package/dist/commands/credits/add.js +2 -2
- package/dist/commands/credits/add.js.map +1 -1
- package/dist/commands/credits/index.js +5 -1
- package/dist/commands/credits/index.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/link.d.ts +77 -0
- package/dist/commands/link.js +530 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.js +9 -0
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/order.js +3 -1
- package/dist/commands/order.js.map +1 -1
- package/dist/commands/payments/methods/delete.js +2 -2
- package/dist/commands/payments/methods/delete.js.map +1 -1
- package/dist/commands/resources.js +50 -7
- package/dist/commands/resources.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/detach.js +1 -1
- package/dist/commands/storage/detach.js.map +1 -1
- package/dist/commands/storage/list.js +6 -2
- package/dist/commands/storage/list.js.map +1 -1
- package/dist/commands/storage/order.d.ts +2 -0
- package/dist/commands/storage/order.js +100 -18
- package/dist/commands/storage/order.js.map +1 -1
- package/dist/commands/storage/resize.js +19 -6
- package/dist/commands/storage/resize.js.map +1 -1
- package/dist/commands/tickets/create.d.ts +2 -0
- package/dist/commands/tickets/create.js +40 -1
- package/dist/commands/tickets/create.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.js +13 -7
- package/dist/commands/tickets/list.js.map +1 -1
- package/dist/commands/tickets/reply.d.ts +2 -0
- package/dist/commands/tickets/reply.js +33 -4
- package/dist/commands/tickets/reply.js.map +1 -1
- package/dist/commands/vds/order.js +72 -7
- package/dist/commands/vds/order.js.map +1 -1
- package/dist/commands/vps/console.js +14 -6
- package/dist/commands/vps/console.js.map +1 -1
- package/dist/commands/vps/details.js +7 -1
- package/dist/commands/vps/details.js.map +1 -1
- package/dist/commands/vps/ip/add.js +76 -9
- package/dist/commands/vps/ip/add.js.map +1 -1
- package/dist/commands/vps/list.js +13 -4
- package/dist/commands/vps/list.js.map +1 -1
- package/dist/commands/vps/order.d.ts +19 -0
- package/dist/commands/vps/order.js +179 -23
- package/dist/commands/vps/order.js.map +1 -1
- package/dist/commands/vps/power.js +2 -2
- package/dist/commands/vps/power.js.map +1 -1
- package/dist/commands/vps/reinstall.js +2 -2
- package/dist/commands/vps/reinstall.js.map +1 -1
- package/dist/commands/vps/resize.js +36 -13
- package/dist/commands/vps/resize.js.map +1 -1
- package/dist/commands/whoami.d.ts +5 -0
- package/dist/commands/whoami.js +8 -3
- 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/scope-aware-help.js +10 -1
- package/dist/help/scope-aware-help.js.map +1 -1
- package/dist/tui/App.js +10 -25
- 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/router.d.ts +1 -1
- package/dist/tui/router.js.map +1 -1
- package/dist/tui/screens/Billing.js +56 -4
- 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 +359 -26
- package/dist/tui/screens/Order.js.map +1 -1
- package/dist/tui/screens/Resources.js +273 -31
- package/dist/tui/screens/Resources.js.map +1 -1
- package/dist/tui/screens/Tickets.js +18 -6
- 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.js +2 -2
- package/dist/version-check-bin.js.map +1 -1
- package/dist/version-check.d.ts +5 -0
- package/dist/version-check.js +6 -1
- package/dist/version-check.js.map +1 -1
- package/package.json +53 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useState, useMemo, useCallback } from "react";
|
|
1
|
+
import React, { useEffect, useState, useMemo, useCallback, useRef } from "react";
|
|
2
2
|
import { Box, Text, useInput } from "ink";
|
|
3
3
|
import TextInput from "ink-text-input";
|
|
4
4
|
import { Panel } from "../components/Panel.js";
|
|
@@ -16,7 +16,10 @@ import { useHeader } from "../hooks/useHeader.js";
|
|
|
16
16
|
import { useMousePause } from "../hooks/useMouse.js";
|
|
17
17
|
import { useRouter } from "../router.js";
|
|
18
18
|
import { colors, statusColor } from "../theme/colors.js";
|
|
19
|
+
import { orderResultMessage } from "../../ui/order-result.js";
|
|
19
20
|
import { glyphs } from "../theme/glyphs.js";
|
|
21
|
+
import { deployPresetRef } from "./deployPreset.js";
|
|
22
|
+
import { RUNTIMES, RUNTIME_LABELS } from "../../functions-support/runtime.js";
|
|
20
23
|
const emptyDraft = {
|
|
21
24
|
kind: null,
|
|
22
25
|
projectId: null,
|
|
@@ -35,6 +38,10 @@ const emptyDraft = {
|
|
|
35
38
|
applyCredits: false,
|
|
36
39
|
paymentMethodId: null,
|
|
37
40
|
paymentKind: "method",
|
|
41
|
+
fnName: "",
|
|
42
|
+
fnPlanTier: null,
|
|
43
|
+
fnRuntime: "node22",
|
|
44
|
+
fnLocationId: null,
|
|
38
45
|
};
|
|
39
46
|
const PROGRESS_STEPS = [
|
|
40
47
|
"kind",
|
|
@@ -46,9 +53,16 @@ const PROGRESS_STEPS = [
|
|
|
46
53
|
"payment",
|
|
47
54
|
"summary",
|
|
48
55
|
];
|
|
49
|
-
function stepsForKind(kind) {
|
|
56
|
+
function stepsForKind(kind, fnLocations = 0) {
|
|
50
57
|
const base = ["kind", "project"];
|
|
51
|
-
if (kind === "
|
|
58
|
+
if (kind === "function") {
|
|
59
|
+
// The location step only appears when there is a choice to make.
|
|
60
|
+
base.push("fn-name", "fn-plan", "fn-runtime");
|
|
61
|
+
if (fnLocations > 1)
|
|
62
|
+
base.push("fn-location");
|
|
63
|
+
base.push("fn-summary");
|
|
64
|
+
}
|
|
65
|
+
else if (kind === "vps") {
|
|
52
66
|
base.push("vps-spec", "image", "hostname", "auth", "payment", "summary");
|
|
53
67
|
}
|
|
54
68
|
else if (kind === "gpu" || kind === "dedicated" || kind === "vds") {
|
|
@@ -83,17 +97,21 @@ export function Order() {
|
|
|
83
97
|
paymentMethods: [],
|
|
84
98
|
creditBalance: 0,
|
|
85
99
|
balanceCurrency: "",
|
|
100
|
+
fnPlans: [],
|
|
101
|
+
fnLocations: [],
|
|
86
102
|
});
|
|
87
103
|
useEffect(() => {
|
|
88
104
|
let cancelled = false;
|
|
89
105
|
(async () => {
|
|
90
106
|
try {
|
|
91
|
-
const [orderCatalog, storageCatalog, projects, methods, balance] = await Promise.all([
|
|
107
|
+
const [orderCatalog, storageCatalog, projects, methods, balance, fnPlans, fnLocations] = await Promise.all([
|
|
92
108
|
api.orders.catalog().catch(() => null),
|
|
93
109
|
api.storage.catalog().catch(() => null),
|
|
94
110
|
api.projects.list().catch(() => []),
|
|
95
111
|
api.payments.methods().catch(() => []),
|
|
96
112
|
api.billing.balance().catch(() => ({})),
|
|
113
|
+
api.functions.plans().catch(() => []),
|
|
114
|
+
api.functions.locations().catch(() => []),
|
|
97
115
|
]);
|
|
98
116
|
if (cancelled)
|
|
99
117
|
return;
|
|
@@ -109,6 +127,8 @@ export function Order() {
|
|
|
109
127
|
paymentMethods: methods,
|
|
110
128
|
creditBalance: Number.isFinite(credit) && credit > 0 ? credit : 0,
|
|
111
129
|
balanceCurrency: balance.currency ?? "",
|
|
130
|
+
fnPlans,
|
|
131
|
+
fnLocations,
|
|
112
132
|
});
|
|
113
133
|
}
|
|
114
134
|
catch (e) {
|
|
@@ -127,10 +147,12 @@ export function Order() {
|
|
|
127
147
|
setDraft((d) => ({ ...d, projectId: def.id }));
|
|
128
148
|
}
|
|
129
149
|
}, [cat.loading, cat.projects, draft.projectId]);
|
|
130
|
-
const visibleSteps = useMemo(() => stepsForKind(draft.kind), [draft.kind]);
|
|
150
|
+
const visibleSteps = useMemo(() => stepsForKind(draft.kind, cat.fnLocations.length), [draft.kind, cat.fnLocations.length]);
|
|
131
151
|
const stepIndex = visibleSteps.indexOf(step);
|
|
132
152
|
const stepNumber = stepIndex >= 0 ? stepIndex + 1 : 1;
|
|
133
153
|
const totalSteps = visibleSteps.length;
|
|
154
|
+
const netEstimate = useMemo(() => estimateMonthlyCost(draft, cat), [draft, cat]);
|
|
155
|
+
const quote = usePreviewQuote(draft, cat, api, netEstimate?.amount ?? 0);
|
|
134
156
|
const goPrev = useCallback(() => {
|
|
135
157
|
if (step === "kind")
|
|
136
158
|
return;
|
|
@@ -144,6 +166,7 @@ export function Order() {
|
|
|
144
166
|
setStep(visibleSteps[idx + 1]);
|
|
145
167
|
}, [step, visibleSteps]);
|
|
146
168
|
const textInputOwnsKeys = step === "hostname" ||
|
|
169
|
+
step === "fn-name" ||
|
|
147
170
|
step === "size" ||
|
|
148
171
|
(step === "auth" && !!draft.authKind) ||
|
|
149
172
|
step === "vps-spec";
|
|
@@ -194,10 +217,25 @@ export function Order() {
|
|
|
194
217
|
React.createElement(Text, { color: colors.dim }, "Esc to return to Dashboard."))));
|
|
195
218
|
}
|
|
196
219
|
else {
|
|
197
|
-
body = (React.createElement(StepRouter, { step: step, draft: draft, setDraft: setDraft, userEmail: header.userEmail, cat: cat, creditBalance: cat.creditBalance, balanceCurrency: cat.balanceCurrency, goNext: goNext,
|
|
220
|
+
body = (React.createElement(StepRouter, { step: step, draft: draft, setDraft: setDraft, userEmail: header.userEmail, api: api, cat: cat, creditBalance: cat.creditBalance, balanceCurrency: cat.balanceCurrency, quote: quote, goNext: goNext, onApp: () => {
|
|
221
|
+
// App: the Deploy walkthrough owns naming, plan (cap-aware) and the
|
|
222
|
+
// paid-plan order; open it at its "New app" step.
|
|
223
|
+
deployPresetRef.current = { newApp: true };
|
|
224
|
+
navigate("deploy");
|
|
225
|
+
}, onSubmit: async () => {
|
|
198
226
|
setStep("submitting");
|
|
199
227
|
try {
|
|
200
|
-
if (draft.kind === "
|
|
228
|
+
if (draft.kind === "function") {
|
|
229
|
+
const loc = cat.fnLocations.length === 1 ? cat.fnLocations[0] : cat.fnLocations.find((l) => l.locationId === draft.fnLocationId);
|
|
230
|
+
const fn = await api.functions.create({
|
|
231
|
+
name: draft.fnName.trim(),
|
|
232
|
+
planTier: draft.fnPlanTier ?? cat.fnPlans[0]?.name ?? "",
|
|
233
|
+
runtime: draft.fnRuntime,
|
|
234
|
+
...(loc ? { locationId: loc.locationId } : {}),
|
|
235
|
+
}, draft.projectId ?? undefined);
|
|
236
|
+
setResult({ ok: true, fn });
|
|
237
|
+
}
|
|
238
|
+
else if (draft.kind === "storage") {
|
|
201
239
|
const out = await api.storage.order({
|
|
202
240
|
name: draft.hostname || "volume",
|
|
203
241
|
size_gb: draft.storageSizeGb ?? 0,
|
|
@@ -267,7 +305,7 @@ export function Order() {
|
|
|
267
305
|
cancelConfirm ? (React.createElement(ConfirmModal, { title: "Cancel this order?", hint: "Your progress is kept until you leave the wizard.", onConfirm: () => navigate("dashboard"), onCancel: () => setCancelConfirm(false) })) : (React.createElement(Box, { flexGrow: 1, justifyContent: "center", alignItems: "flex-start" },
|
|
268
306
|
React.createElement(Box, { flexDirection: "column", width: 80 },
|
|
269
307
|
body,
|
|
270
|
-
React.createElement(LivePriceFooter, { draft: draft, cat: cat })))),
|
|
308
|
+
React.createElement(LivePriceFooter, { draft: draft, cat: cat, quote: quote })))),
|
|
271
309
|
React.createElement(Box, { flexDirection: "column" },
|
|
272
310
|
React.createElement(Tip, null, tipForStep(step, draft, cancelConfirm)),
|
|
273
311
|
React.createElement(StatusBar, { right: [
|
|
@@ -276,22 +314,40 @@ export function Order() {
|
|
|
276
314
|
header.balance ?? "",
|
|
277
315
|
].filter(Boolean) }))));
|
|
278
316
|
}
|
|
279
|
-
function LivePriceFooter({ draft, cat, }) {
|
|
317
|
+
function LivePriceFooter({ draft, cat, quote, }) {
|
|
280
318
|
const est = useMemo(() => estimateMonthlyCost(draft, cat), [draft, cat]);
|
|
281
|
-
const shouldShow = draft.kind !== null && draft.projectId !== null;
|
|
319
|
+
const shouldShow = draft.kind !== null && draft.kind !== "function" && draft.projectId !== null;
|
|
282
320
|
if (!shouldShow)
|
|
283
321
|
return null;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
322
|
+
// A landed, non-degraded server quote is the number — even at zero tax
|
|
323
|
+
// (CLI-M3: the zero-tax quote used to be discarded for client math, which
|
|
324
|
+
// can drift from the seam). Unquoted/degraded → client estimate.
|
|
325
|
+
const showTax = quote.hasTax && !quote.degraded;
|
|
326
|
+
const amount = quote.quoted && !quote.degraded ? quote.total : est?.amount;
|
|
327
|
+
return (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
328
|
+
React.createElement(Box, { paddingX: 2, paddingY: 0, borderStyle: "round", borderColor: colors.dim },
|
|
329
|
+
React.createElement(Text, { color: colors.dim }, "Est. monthly: "),
|
|
330
|
+
amount != null ? (React.createElement(React.Fragment, null,
|
|
331
|
+
React.createElement(Text, { color: colors.accent, bold: true }, `$${amount.toFixed(2)}`),
|
|
332
|
+
React.createElement(Text, { color: colors.dim }, ` · ${est?.label ?? ""}`),
|
|
333
|
+
showTax ? (React.createElement(Text, { color: colors.dim }, ` (incl. ${quote.taxLabel.toLowerCase()})`)) : null)) : (React.createElement(Text, { color: colors.dim }, "-"))),
|
|
334
|
+
quote.degraded ? (React.createElement(Text, { color: colors.warning }, `${quote.taxLabel} estimate unavailable — final total shown at invoice.`)) : null));
|
|
289
335
|
}
|
|
290
336
|
function StepRouter(props) {
|
|
291
337
|
const { step, draft, setDraft, cat, goNext } = props;
|
|
292
338
|
switch (step) {
|
|
293
339
|
case "kind":
|
|
294
|
-
return React.createElement(KindStep, { draft: draft, setDraft: setDraft, goNext: goNext });
|
|
340
|
+
return React.createElement(KindStep, { draft: draft, setDraft: setDraft, goNext: goNext, onApp: props.onApp });
|
|
341
|
+
case "fn-name":
|
|
342
|
+
return React.createElement(FnNameStep, { api: props.api, draft: draft, setDraft: setDraft, goNext: goNext });
|
|
343
|
+
case "fn-plan":
|
|
344
|
+
return React.createElement(FnPlanStep, { plans: cat.fnPlans, draft: draft, setDraft: setDraft, goNext: goNext });
|
|
345
|
+
case "fn-runtime":
|
|
346
|
+
return React.createElement(FnRuntimeStep, { draft: draft, setDraft: setDraft, goNext: goNext });
|
|
347
|
+
case "fn-location":
|
|
348
|
+
return React.createElement(FnLocationStep, { locations: cat.fnLocations, draft: draft, setDraft: setDraft, goNext: goNext });
|
|
349
|
+
case "fn-summary":
|
|
350
|
+
return React.createElement(FnSummaryStep, { draft: draft, cat: cat, onSubmit: props.onSubmit, onEdit: props.onEdit });
|
|
295
351
|
case "project":
|
|
296
352
|
return React.createElement(ProjectStep, { projects: cat.projects, draft: draft, setDraft: setDraft, goNext: goNext });
|
|
297
353
|
case "plan-location":
|
|
@@ -310,21 +366,25 @@ function StepRouter(props) {
|
|
|
310
366
|
return React.createElement(AuthStep, { draft: draft, setDraft: setDraft, goNext: goNext });
|
|
311
367
|
case "payment": {
|
|
312
368
|
const est = estimateMonthlyCost(draft, cat);
|
|
313
|
-
|
|
369
|
+
const { quote } = props;
|
|
370
|
+
const showTax = quote.hasTax && !quote.degraded;
|
|
371
|
+
return (React.createElement(PaymentStep, { methods: cat.paymentMethods, creditBalance: cat.creditBalance, balanceCurrency: cat.balanceCurrency, estimatedCost: showTax ? quote.total : est?.amount ?? 0, quote: quote, draft: draft, setDraft: setDraft, goNext: goNext }));
|
|
314
372
|
}
|
|
315
373
|
case "summary":
|
|
316
|
-
return (React.createElement(SummaryStep, { draft: draft, cat: cat, onSubmit: props.onSubmit, onEdit: props.onEdit }));
|
|
374
|
+
return (React.createElement(SummaryStep, { draft: draft, cat: cat, quote: props.quote, onSubmit: props.onSubmit, onEdit: props.onEdit }));
|
|
317
375
|
case "submitting":
|
|
318
376
|
return (React.createElement(Panel, { paddingX: 3, paddingY: 1, width: 80 },
|
|
319
|
-
React.createElement(Spinner, { label: "Submitting order
|
|
377
|
+
React.createElement(Spinner, { label: draft.kind === "function" ? `Creating ${draft.fnName}…` : "Submitting order…" })));
|
|
320
378
|
case "result":
|
|
321
379
|
return React.createElement(ResultStep, { result: props.result });
|
|
322
380
|
default:
|
|
323
381
|
return React.createElement(Text, null, "-");
|
|
324
382
|
}
|
|
325
383
|
}
|
|
326
|
-
function KindStep({ draft, setDraft, goNext, }) {
|
|
384
|
+
function KindStep({ draft, setDraft, goNext, onApp, }) {
|
|
327
385
|
const items = [
|
|
386
|
+
{ value: "app", label: "App", hint: "managed container; name → plan → deploy" },
|
|
387
|
+
{ value: "function", label: "Function", hint: "serverless; name → plan → runtime → region" },
|
|
328
388
|
{ value: "vps", label: "VPS", hint: "custom CPU/RAM/disk; shared or dedicated cores" },
|
|
329
389
|
{ value: "vds", label: "VDS", hint: "tier-based performance servers (order via web for now)" },
|
|
330
390
|
{ value: "gpu", label: "GPU", hint: "preset GPU-bearing plans" },
|
|
@@ -333,6 +393,10 @@ function KindStep({ draft, setDraft, goNext, }) {
|
|
|
333
393
|
];
|
|
334
394
|
return (React.createElement(Panel, { title: "What are you ordering?", paddingX: 3, paddingY: 1, width: 80 },
|
|
335
395
|
React.createElement(Menu, { items: items, initialIndex: Math.max(0, items.findIndex((i) => i.value === draft.kind)), onSelect: (v) => {
|
|
396
|
+
if (v === "app") {
|
|
397
|
+
onApp();
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
336
400
|
if (v !== draft.kind) {
|
|
337
401
|
setDraft((d) => ({
|
|
338
402
|
...d,
|
|
@@ -352,6 +416,124 @@ function KindStep({ draft, setDraft, goNext, }) {
|
|
|
352
416
|
goNext();
|
|
353
417
|
} })));
|
|
354
418
|
}
|
|
419
|
+
// ---------------------------------------------------------------- Function
|
|
420
|
+
// A function is created straight through POST /functions (no order row, no
|
|
421
|
+
// payment step): name → plan → runtime → (location) → confirm. Mirrors what
|
|
422
|
+
// `synteq function init` does with the API.
|
|
423
|
+
const FN_NAME_RE = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
|
|
424
|
+
function FnNameStep({ api, draft, setDraft, goNext, }) {
|
|
425
|
+
const [value, setValue] = useState(draft.fnName);
|
|
426
|
+
const [err, setErr] = useState(null);
|
|
427
|
+
const [checking, setChecking] = useState(false);
|
|
428
|
+
return (React.createElement(Panel, { title: "Function name", paddingX: 3, paddingY: 1, width: 80 },
|
|
429
|
+
React.createElement(Text, { color: colors.dim }, "Lowercase letters, digits and dashes \u2014 it becomes the hostname."),
|
|
430
|
+
React.createElement(Box, { marginTop: 1 },
|
|
431
|
+
React.createElement(Text, { color: colors.dim }, "Name: "),
|
|
432
|
+
checking ? (React.createElement(Spinner, { label: `Checking ${value.trim()}…` })) : (React.createElement(TextInput, { value: value, onChange: (v) => {
|
|
433
|
+
setValue(v);
|
|
434
|
+
setErr(null);
|
|
435
|
+
}, onSubmit: (v) => {
|
|
436
|
+
const name = v.trim();
|
|
437
|
+
if (!FN_NAME_RE.test(name)) {
|
|
438
|
+
setErr("Use 3–63 lowercase letters, digits and dashes.");
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
setChecking(true);
|
|
442
|
+
api.functions
|
|
443
|
+
.checkName(name)
|
|
444
|
+
.then((check) => {
|
|
445
|
+
if (!check.available) {
|
|
446
|
+
setErr(`"${name}" isn't available${check.reason ? `: ${check.reason}` : "."}`);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
setDraft((d) => ({ ...d, fnName: name }));
|
|
450
|
+
goNext();
|
|
451
|
+
})
|
|
452
|
+
.catch((e) => setErr(e instanceof Error ? e.message : String(e)))
|
|
453
|
+
.finally(() => setChecking(false));
|
|
454
|
+
}, placeholder: "my-fn" }))),
|
|
455
|
+
err ? (React.createElement(Box, { marginTop: 1 },
|
|
456
|
+
React.createElement(Text, { color: colors.error }, err))) : null));
|
|
457
|
+
}
|
|
458
|
+
function fnPlanHint(p) {
|
|
459
|
+
const parts = [
|
|
460
|
+
`${p.memoryMib} MB`,
|
|
461
|
+
p.cpuMillicores ? `${(p.cpuMillicores / 1000).toFixed(2)} cores` : "",
|
|
462
|
+
p.pricePerMillionInvocationsUsd != null ? `$${p.pricePerMillionInvocationsUsd}/M invocations` : "",
|
|
463
|
+
p.pricePerGbSecondUsd != null ? `$${p.pricePerGbSecondUsd}/GB-s` : "",
|
|
464
|
+
p.keepWarmMonthlyUsd != null ? `keep-warm $${p.keepWarmMonthlyUsd}/mo` : "",
|
|
465
|
+
];
|
|
466
|
+
return parts.filter(Boolean).join(" · ");
|
|
467
|
+
}
|
|
468
|
+
function FnPlanStep({ plans, draft, setDraft, goNext, }) {
|
|
469
|
+
if (plans.length === 0) {
|
|
470
|
+
return (React.createElement(Panel, { title: "No function plans", paddingX: 3, paddingY: 1, width: 80 },
|
|
471
|
+
React.createElement(Text, { color: colors.error }, "No function plans are available on this account."),
|
|
472
|
+
React.createElement(Box, { marginTop: 1 },
|
|
473
|
+
React.createElement(Text, { color: colors.dim }, "Esc to go back."))));
|
|
474
|
+
}
|
|
475
|
+
const items = plans.map((p) => ({
|
|
476
|
+
value: p.name,
|
|
477
|
+
label: p.displayName || p.name,
|
|
478
|
+
hint: fnPlanHint(p),
|
|
479
|
+
}));
|
|
480
|
+
return (React.createElement(Panel, { title: "Plan", paddingX: 3, paddingY: 1, width: 80 },
|
|
481
|
+
React.createElement(Text, { color: colors.dim },
|
|
482
|
+
"Pick a plan for ",
|
|
483
|
+
draft.fnName,
|
|
484
|
+
"."),
|
|
485
|
+
React.createElement(Box, { marginTop: 1 },
|
|
486
|
+
React.createElement(Menu, { items: items, initialIndex: Math.max(0, items.findIndex((i) => i.value === draft.fnPlanTier)), onSelect: (v) => {
|
|
487
|
+
setDraft((d) => ({ ...d, fnPlanTier: v }));
|
|
488
|
+
goNext();
|
|
489
|
+
} }))));
|
|
490
|
+
}
|
|
491
|
+
function FnRuntimeStep({ draft, setDraft, goNext, }) {
|
|
492
|
+
const items = RUNTIMES.map((r) => ({ value: r, label: RUNTIME_LABELS[r], hint: r }));
|
|
493
|
+
return (React.createElement(Panel, { title: "Runtime", paddingX: 3, paddingY: 1, width: 80 },
|
|
494
|
+
React.createElement(Menu, { items: items, initialIndex: Math.max(0, items.findIndex((i) => i.value === draft.fnRuntime)), onSelect: (v) => {
|
|
495
|
+
setDraft((d) => ({ ...d, fnRuntime: v }));
|
|
496
|
+
goNext();
|
|
497
|
+
} })));
|
|
498
|
+
}
|
|
499
|
+
function FnLocationStep({ locations, draft, setDraft, goNext, }) {
|
|
500
|
+
const items = locations.map((l) => ({
|
|
501
|
+
value: l.locationId,
|
|
502
|
+
label: l.city || l.code,
|
|
503
|
+
hint: [l.code, l.country].filter(Boolean).join(" · "),
|
|
504
|
+
}));
|
|
505
|
+
return (React.createElement(Panel, { title: "Region", paddingX: 3, paddingY: 1, width: 80 },
|
|
506
|
+
React.createElement(Menu, { items: items, initialIndex: Math.max(0, items.findIndex((i) => i.value === draft.fnLocationId)), onSelect: (v) => {
|
|
507
|
+
setDraft((d) => ({ ...d, fnLocationId: v }));
|
|
508
|
+
goNext();
|
|
509
|
+
} })));
|
|
510
|
+
}
|
|
511
|
+
function FnSummaryStep({ draft, cat, onSubmit, onEdit, }) {
|
|
512
|
+
const projectName = cat.projects.find((p) => p.id === draft.projectId)?.name;
|
|
513
|
+
const plan = cat.fnPlans.find((p) => p.name === draft.fnPlanTier);
|
|
514
|
+
const loc = cat.fnLocations.length === 1
|
|
515
|
+
? cat.fnLocations[0]
|
|
516
|
+
: cat.fnLocations.find((l) => l.locationId === draft.fnLocationId);
|
|
517
|
+
return (React.createElement(Panel, { title: "Create this function?", paddingX: 3, paddingY: 1, width: 80 },
|
|
518
|
+
React.createElement(Box, { flexDirection: "column" },
|
|
519
|
+
React.createElement(Row, { label: "Name", value: draft.fnName }),
|
|
520
|
+
React.createElement(Row, { label: "Project", value: projectName ?? draft.projectId }),
|
|
521
|
+
React.createElement(Row, { label: "Plan", value: plan ? `${plan.displayName || plan.name} · ${fnPlanHint(plan)}` : draft.fnPlanTier }),
|
|
522
|
+
React.createElement(Row, { label: "Runtime", value: RUNTIME_LABELS[draft.fnRuntime] }),
|
|
523
|
+
React.createElement(Row, { label: "Region", value: loc ? `${loc.city || loc.code} (${loc.code})` : "default" }),
|
|
524
|
+
React.createElement(Box, { marginTop: 1 },
|
|
525
|
+
React.createElement(Text, { color: colors.dim }, "Nothing is charged now: runs bill against the plan's credits.")),
|
|
526
|
+
React.createElement(Box, { marginTop: 1 },
|
|
527
|
+
React.createElement(Menu, { items: [
|
|
528
|
+
{ value: "create", label: "Create function", keybind: "enter" },
|
|
529
|
+
{ value: "edit", label: "Edit from start", keybind: "e" },
|
|
530
|
+
], onSelect: (v) => {
|
|
531
|
+
if (v === "create")
|
|
532
|
+
void onSubmit();
|
|
533
|
+
else
|
|
534
|
+
onEdit();
|
|
535
|
+
} })))));
|
|
536
|
+
}
|
|
355
537
|
function ProjectStep({ projects, draft, setDraft, goNext, }) {
|
|
356
538
|
if (projects.length === 0) {
|
|
357
539
|
return (React.createElement(Panel, { title: "No projects on this team", paddingX: 3, paddingY: 1, width: 80 },
|
|
@@ -1126,7 +1308,7 @@ function AuthStep({ draft, setDraft, goNext, }) {
|
|
|
1126
1308
|
React.createElement(Text, { color: colors.error }, err))) : (React.createElement(Box, { marginTop: 1 },
|
|
1127
1309
|
React.createElement(Text, { color: colors.dim }, "Enter to confirm \u00B7 Esc to pick a different auth method.")))));
|
|
1128
1310
|
}
|
|
1129
|
-
function PaymentStep({ methods, creditBalance, balanceCurrency, estimatedCost, draft, setDraft, goNext, }) {
|
|
1311
|
+
function PaymentStep({ methods, creditBalance, balanceCurrency, estimatedCost, quote, draft, setDraft, goNext, }) {
|
|
1130
1312
|
const eligible = methods.filter((m) => !isAch(m));
|
|
1131
1313
|
const creditsCover = estimatedCost > 0 && creditBalance >= estimatedCost;
|
|
1132
1314
|
const rows = [
|
|
@@ -1210,8 +1392,14 @@ function PaymentStep({ methods, creditBalance, balanceCurrency, estimatedCost, d
|
|
|
1210
1392
|
React.createElement(Text, { color: colors.dim }, "Esc to go back."))));
|
|
1211
1393
|
}
|
|
1212
1394
|
const creditsLabel = `$${creditBalance.toFixed(2)}${balanceCurrency ? ` ${balanceCurrency}` : ""}`;
|
|
1395
|
+
const showTaxBreakdown = quote.hasTax && !quote.degraded;
|
|
1213
1396
|
return (React.createElement(Panel, { title: "Payment", paddingX: 3, paddingY: 1, width: 80 },
|
|
1214
1397
|
React.createElement(Box, { flexDirection: "column" },
|
|
1398
|
+
showTaxBreakdown ? (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
1399
|
+
React.createElement(Row, { label: "Subtotal", value: `$${quote.subtotal.toFixed(2)}` }),
|
|
1400
|
+
React.createElement(Row, { label: quote.taxLabel, value: `$${quote.taxTotal.toFixed(2)}` }),
|
|
1401
|
+
React.createElement(Row, { label: "Total", value: `$${quote.total.toFixed(2)}` }))) : quote.degraded ? (React.createElement(Box, { marginBottom: 1 },
|
|
1402
|
+
React.createElement(Text, { color: colors.warning }, `${quote.taxLabel} estimate unavailable — final total shown at invoice.`))) : null,
|
|
1215
1403
|
rows.map((row, i) => {
|
|
1216
1404
|
const focused = i === cursor;
|
|
1217
1405
|
const marker = focused ? `${glyphs.chevronRight} ` : " ";
|
|
@@ -1266,7 +1454,7 @@ function describePaymentMethod(m) {
|
|
|
1266
1454
|
function capitalize(s) {
|
|
1267
1455
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
1268
1456
|
}
|
|
1269
|
-
function SummaryStep({ draft, cat, onSubmit, onEdit, }) {
|
|
1457
|
+
function SummaryStep({ draft, cat, quote, onSubmit, onEdit, }) {
|
|
1270
1458
|
const projectName = cat.projects.find((p) => p.id === draft.projectId)?.name;
|
|
1271
1459
|
const locName = draft.kind === "storage"
|
|
1272
1460
|
? cat.storageCatalog?.locations.find((l) => l.id === draft.locationId)?.city
|
|
@@ -1311,6 +1499,11 @@ function SummaryStep({ draft, cat, onSubmit, onEdit, }) {
|
|
|
1311
1499
|
? "pasted SSH public key"
|
|
1312
1500
|
: "-" })) : null,
|
|
1313
1501
|
React.createElement(Row, { label: "Payment", value: paymentLabel }),
|
|
1502
|
+
quote.hasTax && !quote.degraded ? (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
1503
|
+
React.createElement(Row, { label: "Subtotal", value: `$${quote.subtotal.toFixed(2)}` }),
|
|
1504
|
+
React.createElement(Row, { label: quote.taxLabel, value: `$${quote.taxTotal.toFixed(2)}` }),
|
|
1505
|
+
React.createElement(Row, { label: "Total", value: `$${quote.total.toFixed(2)}` }))) : quote.degraded ? (React.createElement(Box, { marginTop: 1 },
|
|
1506
|
+
React.createElement(Text, { color: colors.warning }, `${quote.taxLabel} estimate unavailable — final total shown at invoice.`))) : null,
|
|
1314
1507
|
React.createElement(Box, { marginTop: 1 },
|
|
1315
1508
|
React.createElement(Menu, { items: [
|
|
1316
1509
|
{ value: "submit", label: "Submit order", keybind: "enter" },
|
|
@@ -1334,6 +1527,19 @@ function ResultStep({ result, }) {
|
|
|
1334
1527
|
return (React.createElement(Panel, { title: "Done", paddingX: 3, paddingY: 1, width: 80 },
|
|
1335
1528
|
React.createElement(Text, { color: colors.dim }, "No result yet.")));
|
|
1336
1529
|
}
|
|
1530
|
+
if (result.ok && "fn" in result) {
|
|
1531
|
+
const fn = result.fn;
|
|
1532
|
+
return (React.createElement(Panel, { title: "Function created", paddingX: 3, paddingY: 1, width: 80, borderColor: colors.success },
|
|
1533
|
+
React.createElement(Box, { flexDirection: "column" },
|
|
1534
|
+
React.createElement(Row, { label: "Function", value: fn.slug }),
|
|
1535
|
+
React.createElement(Row, { label: "URL", value: fn.hostname ? `https://${fn.hostname}` : "-" }),
|
|
1536
|
+
React.createElement(Row, { label: "Plan", value: fn.planTier }),
|
|
1537
|
+
React.createElement(Row, { label: "Runtime", value: RUNTIME_LABELS[fn.runtime] ?? fn.runtime }),
|
|
1538
|
+
React.createElement(Box, { marginTop: 1 },
|
|
1539
|
+
React.createElement(Text, { color: colors.dim }, `Deploy code with \`synteq function deploy ${fn.slug} --dir .\``)),
|
|
1540
|
+
React.createElement(Box, { marginTop: 1 },
|
|
1541
|
+
React.createElement(Text, { color: colors.dim }, "Press Esc or Enter to return to Dashboard.")))));
|
|
1542
|
+
}
|
|
1337
1543
|
if (!result.ok) {
|
|
1338
1544
|
return (React.createElement(Panel, { title: "Order failed", paddingX: 3, paddingY: 1, width: 80, borderColor: colors.error },
|
|
1339
1545
|
React.createElement(Text, { color: colors.error }, result.error),
|
|
@@ -1341,6 +1547,10 @@ function ResultStep({ result, }) {
|
|
|
1341
1547
|
React.createElement(Text, { color: colors.dim }, "Press Esc or Enter to return to Dashboard."))));
|
|
1342
1548
|
}
|
|
1343
1549
|
const color = statusColor(result.status ?? "") ?? colors.success;
|
|
1550
|
+
// QA-21: closing line follows the order status — an unpaid order
|
|
1551
|
+
// (awaiting_customer / payment_pending, no checkout) must never read
|
|
1552
|
+
// "All done".
|
|
1553
|
+
const closing = orderResultMessage(result.status, result.checkoutUrl);
|
|
1344
1554
|
return (React.createElement(Panel, { title: "Order submitted", paddingX: 3, paddingY: 1, width: 80, borderColor: colors.success },
|
|
1345
1555
|
React.createElement(Box, { flexDirection: "column" },
|
|
1346
1556
|
React.createElement(Row, { label: "Status", value: result.status ?? "ok" }),
|
|
@@ -1348,9 +1558,7 @@ function ResultStep({ result, }) {
|
|
|
1348
1558
|
React.createElement(Row, { label: "Invoice id", value: result.invoiceId ?? "-" }),
|
|
1349
1559
|
result.checkoutUrl ? React.createElement(Row, { label: "Checkout URL", value: result.checkoutUrl }) : null,
|
|
1350
1560
|
React.createElement(Box, { marginTop: 1 },
|
|
1351
|
-
React.createElement(Text, { color: color },
|
|
1352
|
-
? "Open the checkout URL in your browser to complete payment."
|
|
1353
|
-
: "All done - see Resources to watch provisioning.")),
|
|
1561
|
+
React.createElement(Text, { color: closing.tone === "warning" ? colors.warning : color }, closing.text)),
|
|
1354
1562
|
React.createElement(Box, { marginTop: 1 },
|
|
1355
1563
|
React.createElement(Text, { color: colors.dim }, "Press Esc or Enter to return to Dashboard.")))));
|
|
1356
1564
|
}
|
|
@@ -1379,6 +1587,10 @@ function tipForStep(step, draft, cancelConfirm) {
|
|
|
1379
1587
|
return "Tab pick/location · ↑↓ move · Enter continue (or Notify me if OOS) · Esc back.";
|
|
1380
1588
|
case "hostname":
|
|
1381
1589
|
return "Type a hostname (5–253 chars). Enter to confirm · Esc back.";
|
|
1590
|
+
case "fn-name":
|
|
1591
|
+
return "Type a name (lowercase letters, digits, dashes). Enter to check and continue · Esc back.";
|
|
1592
|
+
case "fn-summary":
|
|
1593
|
+
return "Enter on Create to create the function. Edit to start over. Esc to go back.";
|
|
1382
1594
|
case "auth":
|
|
1383
1595
|
return draft.authKind
|
|
1384
1596
|
? "Type and Enter to confirm. Esc to pick a different method."
|
|
@@ -1451,7 +1663,9 @@ function estimateMonthlyCost(draft, cat) {
|
|
|
1451
1663
|
cpu * baseCfg.price_per_cpu +
|
|
1452
1664
|
ramGb * baseCfg.price_per_ram_gb +
|
|
1453
1665
|
disk * baseCfg.price_per_disk_gb +
|
|
1454
|
-
|
|
1666
|
+
// Dedicated specs price extra bandwidth at the dedicated rate
|
|
1667
|
+
// (backend pricing.py custom_virtualized_dedicated_price_per_tb).
|
|
1668
|
+
extraTb * (baseCfg.price_per_tb ?? cfg.price_per_tb);
|
|
1455
1669
|
return {
|
|
1456
1670
|
amount,
|
|
1457
1671
|
label: `Custom · ${cpu}c ${ramGb}GB ${disk}GB${draft.customSpec._dedicated ? " · dedicated" : ""}`,
|
|
@@ -1471,4 +1685,123 @@ function estimateMonthlyCost(draft, cat) {
|
|
|
1471
1685
|
}
|
|
1472
1686
|
return null;
|
|
1473
1687
|
}
|
|
1688
|
+
/** Same {kind, spec, quantity} shape `POST /orders` sends (see
|
|
1689
|
+
* `virtualizedOrderInToGenericSpecs` / storage's order body in
|
|
1690
|
+
* `src/api/client.ts`) — the preview must price exactly what create
|
|
1691
|
+
* would charge. Returns null when the draft isn't priceable yet, same
|
|
1692
|
+
* gating as `estimateMonthlyCost`. */
|
|
1693
|
+
function buildPreviewBody(draft) {
|
|
1694
|
+
if (!draft.projectId || !draft.locationId)
|
|
1695
|
+
return null;
|
|
1696
|
+
if (draft.kind === "storage") {
|
|
1697
|
+
if (!draft.storageSizeGb)
|
|
1698
|
+
return null;
|
|
1699
|
+
return {
|
|
1700
|
+
kind: "block_volume",
|
|
1701
|
+
spec: {
|
|
1702
|
+
size_gb: draft.storageSizeGb,
|
|
1703
|
+
project_id: draft.projectId,
|
|
1704
|
+
location_id: draft.locationId,
|
|
1705
|
+
},
|
|
1706
|
+
quantity: 1,
|
|
1707
|
+
};
|
|
1708
|
+
}
|
|
1709
|
+
if (draft.kind === "vps" || draft.kind === "vds" || draft.kind === "gpu" || draft.kind === "dedicated") {
|
|
1710
|
+
const spec = {
|
|
1711
|
+
project_id: draft.projectId,
|
|
1712
|
+
location_id: draft.locationId,
|
|
1713
|
+
// Preview prices independent of image/hostname/auth — omit them so
|
|
1714
|
+
// the quote can fire as soon as spec + location are picked (mirrors
|
|
1715
|
+
// the FE preview's early-fire behaviour and the backend's own
|
|
1716
|
+
// preview-host/preview-volume placeholder injection for identity
|
|
1717
|
+
// fields that don't affect price).
|
|
1718
|
+
};
|
|
1719
|
+
if (draft.planId) {
|
|
1720
|
+
spec.plan_id = draft.planId;
|
|
1721
|
+
}
|
|
1722
|
+
else if (draft.kind === "vds" && draft.tierCategorySlug && draft.tierIndex != null) {
|
|
1723
|
+
spec.tier_category_slug = draft.tierCategorySlug;
|
|
1724
|
+
spec.tier_index = draft.tierIndex;
|
|
1725
|
+
}
|
|
1726
|
+
else if (draft.kind === "vps" && draft.customSpec.cpu_cores && draft.customSpec.ram_gb && draft.customSpec.disk_gb) {
|
|
1727
|
+
spec.custom_cpu_cores = draft.customSpec.cpu_cores;
|
|
1728
|
+
spec.custom_ram_gb = draft.customSpec.ram_gb;
|
|
1729
|
+
spec.custom_disk_gb = draft.customSpec.disk_gb;
|
|
1730
|
+
if (draft.customSpec.bandwidth_tb != null)
|
|
1731
|
+
spec.custom_bandwidth_tb = draft.customSpec.bandwidth_tb;
|
|
1732
|
+
spec.custom_dedicated = !!draft.customSpec._dedicated;
|
|
1733
|
+
}
|
|
1734
|
+
else {
|
|
1735
|
+
return null;
|
|
1736
|
+
}
|
|
1737
|
+
return { kind: "virtualized", spec, quantity: 1 };
|
|
1738
|
+
}
|
|
1739
|
+
return null;
|
|
1740
|
+
}
|
|
1741
|
+
/** Debounced POST /orders/preview keyed on the priced config. Keeps
|
|
1742
|
+
* `net` (the instant client-computed estimate) as both the pre-quote
|
|
1743
|
+
* placeholder and the degraded/error fallback; `hasTax` gates every
|
|
1744
|
+
* breakdown row so a zero-tax order renders identically to today. */
|
|
1745
|
+
function usePreviewQuote(draft, cat, api, net) {
|
|
1746
|
+
const [resp, setResp] = useState(null);
|
|
1747
|
+
// The config the current `resp`/`degraded` was fetched for. While the
|
|
1748
|
+
// draft has changed but the fresh quote hasn't landed yet, this lags
|
|
1749
|
+
// `bodyKey` — the signal that the on-screen quote is stale.
|
|
1750
|
+
const [respKey, setRespKey] = useState(null);
|
|
1751
|
+
const [degraded, setDegraded] = useState(false);
|
|
1752
|
+
const reqIdRef = useRef(0);
|
|
1753
|
+
const body = useMemo(() => buildPreviewBody(draft), [draft]);
|
|
1754
|
+
const bodyKey = body ? JSON.stringify(body) : null;
|
|
1755
|
+
useEffect(() => {
|
|
1756
|
+
if (!bodyKey) {
|
|
1757
|
+
setResp(null);
|
|
1758
|
+
setRespKey(null);
|
|
1759
|
+
setDegraded(false);
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
const reqId = ++reqIdRef.current;
|
|
1763
|
+
const t = setTimeout(() => {
|
|
1764
|
+
api
|
|
1765
|
+
.request("POST", "/orders/preview", { body: JSON.parse(bodyKey) })
|
|
1766
|
+
.then((r) => {
|
|
1767
|
+
if (reqId !== reqIdRef.current)
|
|
1768
|
+
return;
|
|
1769
|
+
setResp(r);
|
|
1770
|
+
setRespKey(bodyKey);
|
|
1771
|
+
setDegraded(!!r.estimate_degraded);
|
|
1772
|
+
})
|
|
1773
|
+
.catch(() => {
|
|
1774
|
+
if (reqId !== reqIdRef.current)
|
|
1775
|
+
return;
|
|
1776
|
+
// This attempt was for the *current* draft: record its key so the
|
|
1777
|
+
// degraded fallback + warning line take over the displayed total,
|
|
1778
|
+
// rather than a stale quote left over from a previous config.
|
|
1779
|
+
setRespKey(bodyKey);
|
|
1780
|
+
setDegraded(true);
|
|
1781
|
+
});
|
|
1782
|
+
}, 400);
|
|
1783
|
+
return () => {
|
|
1784
|
+
clearTimeout(t);
|
|
1785
|
+
};
|
|
1786
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1787
|
+
}, [bodyKey, api]);
|
|
1788
|
+
// Only trust the quote when it was fetched for the *current* draft. During
|
|
1789
|
+
// the debounce + round-trip after an edit, `respKey !== bodyKey`, so we fall
|
|
1790
|
+
// back to the instant net estimate (a clean "estimating…" placeholder) as the
|
|
1791
|
+
// comment above describes — instead of showing the prior config's total/tax.
|
|
1792
|
+
const fresh = respKey === bodyKey;
|
|
1793
|
+
const quoted = resp != null && fresh && !degraded;
|
|
1794
|
+
const taxTotal = quoted ? Number(resp.tax_total) : 0;
|
|
1795
|
+
const subtotal = quoted ? Number(resp.subtotal) : net;
|
|
1796
|
+
const total = quoted ? Number(resp.total) : net;
|
|
1797
|
+
return {
|
|
1798
|
+
subtotal,
|
|
1799
|
+
taxTotal,
|
|
1800
|
+
total,
|
|
1801
|
+
taxLabel: (quoted && resp.tax_label) || "Tax",
|
|
1802
|
+
degraded: !!bodyKey && fresh && degraded,
|
|
1803
|
+
hasTax: quoted && taxTotal > 0,
|
|
1804
|
+
quoted,
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1474
1807
|
//# sourceMappingURL=Order.js.map
|