@celljs/cli 3.9.0 → 4.0.0
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/README.md +442 -1
- package/agent/guide.md +39 -0
- package/bin/cell.js +2 -0
- package/lib/agent/agent-guide.d.ts +39 -0
- package/lib/agent/agent-guide.d.ts.map +1 -0
- package/lib/agent/agent-guide.js +67 -0
- package/lib/agent/agent-guide.js.map +1 -0
- package/lib/build/executable-compiler.d.ts +44 -0
- package/lib/build/executable-compiler.d.ts.map +1 -0
- package/lib/build/executable-compiler.js +145 -0
- package/lib/build/executable-compiler.js.map +1 -0
- package/lib/build/executable-compiler.spec.d.ts +2 -0
- package/lib/build/executable-compiler.spec.d.ts.map +1 -0
- package/lib/build/executable-compiler.spec.js +71 -0
- package/lib/build/executable-compiler.spec.js.map +1 -0
- package/lib/build/single-compile.spec.d.ts +2 -0
- package/lib/build/single-compile.spec.d.ts.map +1 -0
- package/lib/build/single-compile.spec.js +135 -0
- package/lib/build/single-compile.spec.js.map +1 -0
- package/lib/check/project-checker.d.ts +85 -0
- package/lib/check/project-checker.d.ts.map +1 -0
- package/lib/check/project-checker.js +332 -0
- package/lib/check/project-checker.js.map +1 -0
- package/lib/check/project-checker.spec.d.ts +2 -0
- package/lib/check/project-checker.spec.d.ts.map +1 -0
- package/lib/check/project-checker.spec.js +147 -0
- package/lib/check/project-checker.spec.js.map +1 -0
- package/lib/cli/agent-command.d.ts +15 -0
- package/lib/cli/agent-command.d.ts.map +1 -0
- package/lib/cli/agent-command.js +42 -0
- package/lib/cli/agent-command.js.map +1 -0
- package/lib/cli/build-command.d.ts +84 -0
- package/lib/cli/build-command.d.ts.map +1 -0
- package/lib/cli/build-command.js +170 -0
- package/lib/cli/build-command.js.map +1 -0
- package/lib/cli/cell-cli.d.ts +35 -0
- package/lib/cli/cell-cli.d.ts.map +1 -0
- package/lib/cli/cell-cli.js +159 -0
- package/lib/cli/cell-cli.js.map +1 -0
- package/lib/cli/cell-cli.spec.d.ts +2 -0
- package/lib/cli/cell-cli.spec.d.ts.map +1 -0
- package/lib/cli/cell-cli.spec.js +195 -0
- package/lib/cli/cell-cli.spec.js.map +1 -0
- package/lib/cli/check-command.d.ts +31 -0
- package/lib/cli/check-command.d.ts.map +1 -0
- package/lib/cli/check-command.js +67 -0
- package/lib/cli/check-command.js.map +1 -0
- package/lib/cli/command.d.ts +24 -0
- package/lib/cli/command.d.ts.map +1 -0
- package/lib/cli/command.js +10 -0
- package/lib/cli/command.js.map +1 -0
- package/lib/cli/config-command.d.ts +29 -0
- package/lib/cli/config-command.d.ts.map +1 -0
- package/lib/cli/config-command.js +71 -0
- package/lib/cli/config-command.js.map +1 -0
- package/lib/cli/config-command.spec.d.ts +2 -0
- package/lib/cli/config-command.spec.d.ts.map +1 -0
- package/lib/cli/config-command.spec.js +79 -0
- package/lib/cli/config-command.spec.js.map +1 -0
- package/lib/cli/deploy-command.d.ts +41 -0
- package/lib/cli/deploy-command.d.ts.map +1 -0
- package/lib/cli/deploy-command.js +114 -0
- package/lib/cli/deploy-command.js.map +1 -0
- package/lib/cli/dev-command.d.ts +47 -0
- package/lib/cli/dev-command.d.ts.map +1 -0
- package/lib/cli/dev-command.js +219 -0
- package/lib/cli/dev-command.js.map +1 -0
- package/lib/cli/dev-command.spec.d.ts +2 -0
- package/lib/cli/dev-command.spec.d.ts.map +1 -0
- package/lib/cli/dev-command.spec.js +149 -0
- package/lib/cli/dev-command.spec.js.map +1 -0
- package/lib/cli/docs-command.d.ts +19 -0
- package/lib/cli/docs-command.d.ts.map +1 -0
- package/lib/cli/docs-command.js +47 -0
- package/lib/cli/docs-command.js.map +1 -0
- package/lib/cli/info-command.d.ts +44 -0
- package/lib/cli/info-command.d.ts.map +1 -0
- package/lib/cli/info-command.js +39 -0
- package/lib/cli/info-command.js.map +1 -0
- package/lib/cli/info-command.spec.d.ts +2 -0
- package/lib/cli/info-command.spec.d.ts.map +1 -0
- package/lib/cli/info-command.spec.js +236 -0
- package/lib/cli/info-command.spec.js.map +1 -0
- package/lib/cli/init-command.d.ts +20 -0
- package/lib/cli/init-command.d.ts.map +1 -0
- package/lib/cli/init-command.js +43 -0
- package/lib/cli/init-command.js.map +1 -0
- package/lib/cli/main.d.ts +2 -0
- package/lib/cli/main.d.ts.map +1 -0
- package/lib/cli/main.js +3 -0
- package/lib/cli/main.js.map +1 -0
- package/lib/cli/mcp-command.d.ts +34 -0
- package/lib/cli/mcp-command.d.ts.map +1 -0
- package/lib/cli/mcp-command.js +85 -0
- package/lib/cli/mcp-command.js.map +1 -0
- package/lib/cli/mcp-command.spec.d.ts +2 -0
- package/lib/cli/mcp-command.spec.d.ts.map +1 -0
- package/lib/cli/mcp-command.spec.js +132 -0
- package/lib/cli/mcp-command.spec.js.map +1 -0
- package/lib/cli/preview-command.d.ts +24 -0
- package/lib/cli/preview-command.d.ts.map +1 -0
- package/lib/cli/preview-command.js +91 -0
- package/lib/cli/preview-command.js.map +1 -0
- package/lib/cli/reporter.d.ts +26 -0
- package/lib/cli/reporter.d.ts.map +1 -0
- package/lib/cli/reporter.js +58 -0
- package/lib/cli/reporter.js.map +1 -0
- package/lib/config/config-build.spec.d.ts +2 -0
- package/lib/config/config-build.spec.d.ts.map +1 -0
- package/lib/config/config-build.spec.js +111 -0
- package/lib/config/config-build.spec.js.map +1 -0
- package/lib/config/config-explainer.d.ts +48 -0
- package/lib/config/config-explainer.d.ts.map +1 -0
- package/lib/config/config-explainer.js +130 -0
- package/lib/config/config-explainer.js.map +1 -0
- package/lib/config/config-file-loader.d.ts +22 -0
- package/lib/config/config-file-loader.d.ts.map +1 -0
- package/lib/config/config-file-loader.js +63 -0
- package/lib/config/config-file-loader.js.map +1 -0
- package/lib/config/config-resolver.d.ts +111 -0
- package/lib/config/config-resolver.d.ts.map +1 -0
- package/lib/config/config-resolver.js +215 -0
- package/lib/config/config-resolver.js.map +1 -0
- package/lib/config/config-resolver.spec.d.ts +2 -0
- package/lib/config/config-resolver.spec.d.ts.map +1 -0
- package/lib/config/config-resolver.spec.js +159 -0
- package/lib/config/config-resolver.spec.js.map +1 -0
- package/lib/config/config-validator.d.ts +35 -0
- package/lib/config/config-validator.d.ts.map +1 -0
- package/lib/config/config-validator.js +160 -0
- package/lib/config/config-validator.js.map +1 -0
- package/lib/config/config-validator.spec.d.ts +2 -0
- package/lib/config/config-validator.spec.d.ts.map +1 -0
- package/lib/config/config-validator.spec.js +77 -0
- package/lib/config/config-validator.spec.js.map +1 -0
- package/lib/config/define-config.d.ts +4 -0
- package/lib/config/define-config.d.ts.map +1 -0
- package/lib/config/define-config.js +5 -0
- package/lib/config/define-config.js.map +1 -0
- package/lib/config/types.d.ts +53 -0
- package/lib/config/types.d.ts.map +1 -0
- package/lib/config/types.js +2 -0
- package/lib/config/types.js.map +1 -0
- package/lib/deploy/cloud-api.d.ts +58 -0
- package/lib/deploy/cloud-api.d.ts.map +1 -0
- package/lib/deploy/cloud-api.js +189 -0
- package/lib/deploy/cloud-api.js.map +1 -0
- package/lib/deploy/code-package.d.ts +15 -0
- package/lib/deploy/code-package.d.ts.map +1 -0
- package/lib/deploy/code-package.js +40 -0
- package/lib/deploy/code-package.js.map +1 -0
- package/lib/deploy/deploy-utils.spec.d.ts +2 -0
- package/lib/deploy/deploy-utils.spec.d.ts.map +1 -0
- package/lib/deploy/deploy-utils.spec.js +56 -0
- package/lib/deploy/deploy-utils.spec.js.map +1 -0
- package/lib/deploy/deployer-registry.d.ts +11 -0
- package/lib/deploy/deployer-registry.d.ts.map +1 -0
- package/lib/deploy/deployer-registry.js +40 -0
- package/lib/deploy/deployer-registry.js.map +1 -0
- package/lib/deploy/request-signer.d.ts +51 -0
- package/lib/deploy/request-signer.d.ts.map +1 -0
- package/lib/deploy/request-signer.js +109 -0
- package/lib/deploy/request-signer.js.map +1 -0
- package/lib/deploy/zip-writer.d.ts +32 -0
- package/lib/deploy/zip-writer.d.ts.map +1 -0
- package/lib/deploy/zip-writer.js +114 -0
- package/lib/deploy/zip-writer.js.map +1 -0
- package/lib/docs/docs-index.d.ts +54 -0
- package/lib/docs/docs-index.d.ts.map +1 -0
- package/lib/docs/docs-index.js +140 -0
- package/lib/docs/docs-index.js.map +1 -0
- package/lib/docs/docs-index.spec.d.ts +2 -0
- package/lib/docs/docs-index.spec.d.ts.map +1 -0
- package/lib/docs/docs-index.spec.js +52 -0
- package/lib/docs/docs-index.spec.js.map +1 -0
- package/lib/events/event-bus.d.ts +30 -0
- package/lib/events/event-bus.d.ts.map +1 -0
- package/lib/events/event-bus.js +81 -0
- package/lib/events/event-bus.js.map +1 -0
- package/lib/events/event-bus.spec.d.ts +2 -0
- package/lib/events/event-bus.spec.d.ts.map +1 -0
- package/lib/events/event-bus.spec.js +69 -0
- package/lib/events/event-bus.spec.js.map +1 -0
- package/lib/events/hook-runner.d.ts +27 -0
- package/lib/events/hook-runner.d.ts.map +1 -0
- package/lib/events/hook-runner.js +65 -0
- package/lib/events/hook-runner.js.map +1 -0
- package/lib/events/hook-runner.spec.d.ts +2 -0
- package/lib/events/hook-runner.spec.d.ts.map +1 -0
- package/lib/events/hook-runner.spec.js +36 -0
- package/lib/events/hook-runner.spec.js.map +1 -0
- package/lib/index.d.ts +57 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +57 -2
- package/lib/index.js.map +1 -1
- package/lib/info/project-inspector.d.ts +143 -0
- package/lib/info/project-inspector.d.ts.map +1 -0
- package/lib/info/project-inspector.js +244 -0
- package/lib/info/project-inspector.js.map +1 -0
- package/lib/init/project-initializer.d.ts +44 -0
- package/lib/init/project-initializer.d.ts.map +1 -0
- package/lib/init/project-initializer.js +90 -0
- package/lib/init/project-initializer.js.map +1 -0
- package/lib/init/project-initializer.spec.d.ts +2 -0
- package/lib/init/project-initializer.spec.d.ts.map +1 -0
- package/lib/init/project-initializer.spec.js +88 -0
- package/lib/init/project-initializer.spec.js.map +1 -0
- package/lib/mcp/dev-activity.d.ts +34 -0
- package/lib/mcp/dev-activity.d.ts.map +1 -0
- package/lib/mcp/dev-activity.js +46 -0
- package/lib/mcp/dev-activity.js.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.d.ts +62 -0
- package/lib/mcp/dev-mcp-endpoint.d.ts.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.js +280 -0
- package/lib/mcp/dev-mcp-endpoint.js.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.spec.d.ts +2 -0
- package/lib/mcp/dev-mcp-endpoint.spec.d.ts.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.spec.js +143 -0
- package/lib/mcp/dev-mcp-endpoint.spec.js.map +1 -0
- package/lib/mcp/mcp-server.d.ts +64 -0
- package/lib/mcp/mcp-server.d.ts.map +1 -0
- package/lib/mcp/mcp-server.js +201 -0
- package/lib/mcp/mcp-server.js.map +1 -0
- package/lib/mcp/mcp-server.spec.d.ts +2 -0
- package/lib/mcp/mcp-server.spec.d.ts.map +1 -0
- package/lib/mcp/mcp-server.spec.js +136 -0
- package/lib/mcp/mcp-server.spec.js.map +1 -0
- package/lib/mcp/project-mcp-tools.d.ts +35 -0
- package/lib/mcp/project-mcp-tools.d.ts.map +1 -0
- package/lib/mcp/project-mcp-tools.js +199 -0
- package/lib/mcp/project-mcp-tools.js.map +1 -0
- package/lib/modules/module-host.d.ts +118 -0
- package/lib/modules/module-host.d.ts.map +1 -0
- package/lib/modules/module-host.js +405 -0
- package/lib/modules/module-host.js.map +1 -0
- package/lib/modules/module-host.spec.d.ts +2 -0
- package/lib/modules/module-host.spec.d.ts.map +1 -0
- package/lib/modules/module-host.spec.js +220 -0
- package/lib/modules/module-host.spec.js.map +1 -0
- package/lib/preset/builtin-presets.d.ts +9 -0
- package/lib/preset/builtin-presets.d.ts.map +1 -0
- package/lib/preset/builtin-presets.js +24 -0
- package/lib/preset/builtin-presets.js.map +1 -0
- package/lib/preset/cloudflare/cloudflare-deployer.d.ts +26 -0
- package/lib/preset/cloudflare/cloudflare-deployer.d.ts.map +1 -0
- package/lib/preset/cloudflare/cloudflare-deployer.js +116 -0
- package/lib/preset/cloudflare/cloudflare-deployer.js.map +1 -0
- package/lib/preset/cloudflare/cloudflare-preset.d.ts +16 -0
- package/lib/preset/cloudflare/cloudflare-preset.d.ts.map +1 -0
- package/lib/preset/cloudflare/cloudflare-preset.js +97 -0
- package/lib/preset/cloudflare/cloudflare-preset.js.map +1 -0
- package/lib/preset/cloudflare/cloudflare.spec.d.ts +2 -0
- package/lib/preset/cloudflare/cloudflare.spec.d.ts.map +1 -0
- package/lib/preset/cloudflare/cloudflare.spec.js +212 -0
- package/lib/preset/cloudflare/cloudflare.spec.js.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.d.ts +50 -0
- package/lib/preset/cloudflare/wrangler-config.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.js +160 -0
- package/lib/preset/cloudflare/wrangler-config.js.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.spec.d.ts +2 -0
- package/lib/preset/cloudflare/wrangler-config.spec.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.spec.js +112 -0
- package/lib/preset/cloudflare/wrangler-config.spec.js.map +1 -0
- package/lib/preset/cloudflare/wrangler.d.ts +38 -0
- package/lib/preset/cloudflare/wrangler.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler.js +90 -0
- package/lib/preset/cloudflare/wrangler.js.map +1 -0
- package/lib/preset/cloudflare/wrangler.spec.d.ts +2 -0
- package/lib/preset/cloudflare/wrangler.spec.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler.spec.js +64 -0
- package/lib/preset/cloudflare/wrangler.spec.js.map +1 -0
- package/lib/preset/fc/fc-deployer.d.ts +50 -0
- package/lib/preset/fc/fc-deployer.d.ts.map +1 -0
- package/lib/preset/fc/fc-deployer.js +209 -0
- package/lib/preset/fc/fc-deployer.js.map +1 -0
- package/lib/preset/fc/fc-preset.d.ts +20 -0
- package/lib/preset/fc/fc-preset.d.ts.map +1 -0
- package/lib/preset/fc/fc-preset.js +46 -0
- package/lib/preset/fc/fc-preset.js.map +1 -0
- package/lib/preset/lambda/lambda-deployer.d.ts +50 -0
- package/lib/preset/lambda/lambda-deployer.d.ts.map +1 -0
- package/lib/preset/lambda/lambda-deployer.js +274 -0
- package/lib/preset/lambda/lambda-deployer.js.map +1 -0
- package/lib/preset/lambda/lambda-preset.d.ts +14 -0
- package/lib/preset/lambda/lambda-preset.d.ts.map +1 -0
- package/lib/preset/lambda/lambda-preset.js +44 -0
- package/lib/preset/lambda/lambda-preset.js.map +1 -0
- package/lib/preset/preset-output.d.ts +19 -0
- package/lib/preset/preset-output.d.ts.map +1 -0
- package/lib/preset/preset-output.js +45 -0
- package/lib/preset/preset-output.js.map +1 -0
- package/lib/preset/preset-registry.d.ts +16 -0
- package/lib/preset/preset-registry.d.ts.map +1 -0
- package/lib/preset/preset-registry.js +58 -0
- package/lib/preset/preset-registry.js.map +1 -0
- package/lib/preset/preset-registry.spec.d.ts +2 -0
- package/lib/preset/preset-registry.spec.d.ts.map +1 -0
- package/lib/preset/preset-registry.spec.js +28 -0
- package/lib/preset/preset-registry.spec.js.map +1 -0
- package/lib/preset/scf/scf-deployer.d.ts +54 -0
- package/lib/preset/scf/scf-deployer.d.ts.map +1 -0
- package/lib/preset/scf/scf-deployer.js +202 -0
- package/lib/preset/scf/scf-deployer.js.map +1 -0
- package/lib/preset/scf/scf-preset.d.ts +19 -0
- package/lib/preset/scf/scf-preset.d.ts.map +1 -0
- package/lib/preset/scf/scf-preset.js +43 -0
- package/lib/preset/scf/scf-preset.js.map +1 -0
- package/lib/preset/serverless-deployers.spec.d.ts +2 -0
- package/lib/preset/serverless-deployers.spec.d.ts.map +1 -0
- package/lib/preset/serverless-deployers.spec.js +307 -0
- package/lib/preset/serverless-deployers.spec.js.map +1 -0
- package/lib/preset/serverless-presets.spec.d.ts +2 -0
- package/lib/preset/serverless-presets.spec.d.ts.map +1 -0
- package/lib/preset/serverless-presets.spec.js +280 -0
- package/lib/preset/serverless-presets.spec.js.map +1 -0
- package/lib/preset/serverless-scripts.d.ts +29 -0
- package/lib/preset/serverless-scripts.d.ts.map +1 -0
- package/lib/preset/serverless-scripts.js +120 -0
- package/lib/preset/serverless-scripts.js.map +1 -0
- package/lib/preset/vercel/vercel-deployer.d.ts +38 -0
- package/lib/preset/vercel/vercel-deployer.d.ts.map +1 -0
- package/lib/preset/vercel/vercel-deployer.js +160 -0
- package/lib/preset/vercel/vercel-deployer.js.map +1 -0
- package/lib/preset/vercel/vercel-preset.d.ts +19 -0
- package/lib/preset/vercel/vercel-preset.d.ts.map +1 -0
- package/lib/preset/vercel/vercel-preset.js +102 -0
- package/lib/preset/vercel/vercel-preset.js.map +1 -0
- package/lib/test/fixture-project.d.ts +17 -0
- package/lib/test/fixture-project.d.ts.map +1 -0
- package/lib/test/fixture-project.js +43 -0
- package/lib/test/fixture-project.js.map +1 -0
- package/lib/testing/create-test-app.d.ts +27 -0
- package/lib/testing/create-test-app.d.ts.map +1 -0
- package/lib/testing/create-test-app.js +54 -0
- package/lib/testing/create-test-app.js.map +1 -0
- package/lib/testing/create-test-app.spec.d.ts +2 -0
- package/lib/testing/create-test-app.spec.d.ts.map +1 -0
- package/lib/testing/create-test-app.spec.js +66 -0
- package/lib/testing/create-test-app.spec.js.map +1 -0
- package/lib/toolchain/toolchain.d.ts +49 -0
- package/lib/toolchain/toolchain.d.ts.map +1 -0
- package/lib/toolchain/toolchain.js +100 -0
- package/lib/toolchain/toolchain.js.map +1 -0
- package/lib/utils/json-util.d.ts +11 -0
- package/lib/utils/json-util.d.ts.map +1 -0
- package/lib/utils/json-util.js +73 -0
- package/lib/utils/json-util.js.map +1 -0
- package/lib/utils/json-util.spec.d.ts +2 -0
- package/lib/utils/json-util.spec.d.ts.map +1 -0
- package/lib/utils/json-util.spec.js +18 -0
- package/lib/utils/json-util.spec.js.map +1 -0
- package/lib/utils/text-util.d.ts +19 -0
- package/lib/utils/text-util.d.ts.map +1 -0
- package/lib/utils/text-util.js +66 -0
- package/lib/utils/text-util.js.map +1 -0
- package/lib/utils/text-util.spec.d.ts +2 -0
- package/lib/utils/text-util.spec.d.ts.map +1 -0
- package/lib/utils/text-util.spec.js +22 -0
- package/lib/utils/text-util.spec.js.map +1 -0
- package/package.json +28 -30
- package/src/agent/agent-guide.ts +90 -0
- package/src/build/executable-compiler.ts +179 -0
- package/src/check/project-checker.ts +365 -0
- package/src/cli/agent-command.ts +46 -0
- package/src/cli/build-command.ts +189 -0
- package/src/cli/cell-cli.ts +174 -0
- package/src/cli/check-command.ts +74 -0
- package/src/cli/command.ts +29 -0
- package/src/cli/config-command.ts +73 -0
- package/src/cli/deploy-command.ts +122 -0
- package/src/cli/dev-command.ts +232 -0
- package/src/cli/docs-command.ts +53 -0
- package/src/cli/info-command.ts +40 -0
- package/src/cli/init-command.ts +53 -0
- package/src/cli/main.ts +3 -0
- package/src/cli/mcp-command.ts +98 -0
- package/src/cli/preview-command.ts +98 -0
- package/src/cli/reporter.ts +67 -0
- package/src/config/config-explainer.ts +158 -0
- package/src/config/config-file-loader.ts +76 -0
- package/src/config/config-resolver.ts +300 -0
- package/src/config/config-validator.ts +208 -0
- package/src/config/define-config.ts +6 -0
- package/src/config/types.ts +57 -0
- package/src/deploy/cloud-api.ts +194 -0
- package/src/deploy/code-package.ts +44 -0
- package/src/deploy/deployer-registry.ts +44 -0
- package/src/deploy/request-signer.ts +155 -0
- package/src/deploy/zip-writer.ts +132 -0
- package/src/docs/docs-index.ts +174 -0
- package/src/events/event-bus.ts +94 -0
- package/src/events/hook-runner.ts +78 -0
- package/src/index.ts +57 -0
- package/src/info/project-inspector.ts +352 -0
- package/src/init/project-initializer.ts +111 -0
- package/src/mcp/dev-activity.ts +71 -0
- package/src/mcp/dev-mcp-endpoint.ts +323 -0
- package/src/mcp/mcp-server.ts +251 -0
- package/src/mcp/project-mcp-tools.ts +216 -0
- package/src/modules/module-host.ts +489 -0
- package/src/preset/builtin-presets.ts +26 -0
- package/src/preset/cloudflare/cloudflare-deployer.ts +126 -0
- package/src/preset/cloudflare/cloudflare-preset.ts +97 -0
- package/src/preset/cloudflare/wrangler-config.ts +173 -0
- package/src/preset/cloudflare/wrangler.ts +113 -0
- package/src/preset/fc/fc-deployer.ts +237 -0
- package/src/preset/fc/fc-preset.ts +51 -0
- package/src/preset/lambda/lambda-deployer.ts +317 -0
- package/src/preset/lambda/lambda-preset.ts +45 -0
- package/src/preset/preset-output.ts +55 -0
- package/src/preset/preset-registry.ts +65 -0
- package/src/preset/scf/scf-deployer.ts +232 -0
- package/src/preset/scf/scf-preset.ts +45 -0
- package/src/preset/serverless-scripts.ts +132 -0
- package/src/preset/vercel/vercel-deployer.ts +168 -0
- package/src/preset/vercel/vercel-preset.ts +111 -0
- package/src/test/fixture-project.ts +50 -0
- package/src/testing/create-test-app.ts +73 -0
- package/src/toolchain/toolchain.ts +121 -0
- package/src/utils/json-util.ts +67 -0
- package/src/utils/text-util.ts +68 -0
- package/templates/backend/README.md +13 -0
- package/templates/backend/_gitignore +5 -0
- package/templates/backend/cell.yml +3 -0
- package/templates/backend/package.json +23 -0
- package/templates/{file-service/src → backend/src/node}/home-controller.ts +5 -2
- package/templates/{file-service/src → backend/src/node}/module.ts +0 -1
- package/templates/backend/template.json +3 -0
- package/templates/backend/test/app.spec.ts +19 -0
- package/templates/backend/tsconfig.json +25 -0
- package/templates/fullstack/README.md +13 -0
- package/templates/fullstack/_gitignore +5 -0
- package/templates/fullstack/cell.yml +6 -0
- package/templates/fullstack/package.json +27 -0
- package/templates/fullstack/src/browser/home.view.tsx +19 -0
- package/templates/{cell-component/src → fullstack/src/browser}/module.ts +1 -1
- package/templates/fullstack/src/common/greeting-protocol.ts +5 -0
- package/templates/fullstack/src/node/greeting-server.ts +13 -0
- package/templates/{admin-app/src/browser → fullstack/src/node}/module.ts +2 -1
- package/templates/fullstack/template.json +3 -0
- package/templates/fullstack/test/app.spec.ts +18 -0
- package/templates/fullstack/tsconfig.json +27 -0
- package/bin/cell +0 -2
- package/lib/build/build-manager.d.ts +0 -9
- package/lib/build/build-manager.d.ts.map +0 -1
- package/lib/build/build-manager.js +0 -41
- package/lib/build/build-manager.js.map +0 -1
- package/lib/build/build.d.ts +0 -6
- package/lib/build/build.d.ts.map +0 -1
- package/lib/build/build.js +0 -16
- package/lib/build/build.js.map +0 -1
- package/lib/cell-main.d.ts +0 -2
- package/lib/cell-main.d.ts.map +0 -1
- package/lib/cell-main.js +0 -110
- package/lib/cell-main.js.map +0 -1
- package/lib/cell.d.ts +0 -2
- package/lib/cell.d.ts.map +0 -1
- package/lib/cell.js +0 -194
- package/lib/cell.js.map +0 -1
- package/lib/config/config.d.ts +0 -12
- package/lib/config/config.d.ts.map +0 -1
- package/lib/config/config.js +0 -48
- package/lib/config/config.js.map +0 -1
- package/lib/deploy/deploy.d.ts +0 -7
- package/lib/deploy/deploy.d.ts.map +0 -1
- package/lib/deploy/deploy.js +0 -30
- package/lib/deploy/deploy.js.map +0 -1
- package/lib/info/info.d.ts +0 -6
- package/lib/info/info.d.ts.map +0 -1
- package/lib/info/info.js +0 -21
- package/lib/info/info.js.map +0 -1
- package/lib/init/init-manager.d.ts +0 -33
- package/lib/init/init-manager.d.ts.map +0 -1
- package/lib/init/init-manager.js +0 -141
- package/lib/init/init-manager.js.map +0 -1
- package/lib/init/init.d.ts +0 -4
- package/lib/init/init.d.ts.map +0 -1
- package/lib/init/init.js +0 -17
- package/lib/init/init.js.map +0 -1
- package/lib/init/templates.d.ts +0 -2
- package/lib/init/templates.d.ts.map +0 -1
- package/lib/init/templates.js +0 -23
- package/lib/init/templates.js.map +0 -1
- package/lib/package.spec.d.ts +0 -2
- package/lib/package.spec.d.ts.map +0 -1
- package/lib/package.spec.js +0 -7
- package/lib/package.spec.js.map +0 -1
- package/lib/props/props.d.ts +0 -9
- package/lib/props/props.d.ts.map +0 -1
- package/lib/props/props.js +0 -49
- package/lib/props/props.js.map +0 -1
- package/lib/serve/serve-manager.d.ts +0 -8
- package/lib/serve/serve-manager.d.ts.map +0 -1
- package/lib/serve/serve-manager.js +0 -44
- package/lib/serve/serve-manager.js.map +0 -1
- package/lib/serve/serve.d.ts +0 -8
- package/lib/serve/serve.d.ts.map +0 -1
- package/lib/serve/serve.js +0 -25
- package/lib/serve/serve.js.map +0 -1
- package/lib/update/update.d.ts +0 -9
- package/lib/update/update.d.ts.map +0 -1
- package/lib/update/update.js +0 -56
- package/lib/update/update.js.map +0 -1
- package/lib/utils/banner-util.d.ts +0 -6
- package/lib/utils/banner-util.d.ts.map +0 -1
- package/lib/utils/banner-util.js +0 -44
- package/lib/utils/banner-util.js.map +0 -1
- package/lib/utils/index.d.ts +0 -2
- package/lib/utils/index.d.ts.map +0 -1
- package/lib/utils/index.js +0 -18
- package/lib/utils/index.js.map +0 -1
- package/src/build/build-manager.ts +0 -50
- package/src/build/build.ts +0 -17
- package/src/cell-main.ts +0 -125
- package/src/cell.ts +0 -215
- package/src/config/config.ts +0 -56
- package/src/deploy/deploy.ts +0 -31
- package/src/info/info.ts +0 -23
- package/src/init/init-manager.ts +0 -163
- package/src/init/init.ts +0 -15
- package/src/init/templates.ts +0 -19
- package/src/package.spec.ts +0 -5
- package/src/props/props.ts +0 -48
- package/src/serve/serve-manager.ts +0 -51
- package/src/serve/serve.ts +0 -29
- package/src/update/update.ts +0 -61
- package/src/utils/banner-util.ts +0 -41
- package/src/utils/index.ts +0 -1
- package/templates/accounts/README.md +0 -76
- package/templates/accounts/cell-database.yml +0 -17
- package/templates/accounts/cell-locale.yml +0 -17
- package/templates/accounts/cell-oauth2.0.yml +0 -8
- package/templates/accounts/cell-theme.yml +0 -9
- package/templates/accounts/cell.yml +0 -10
- package/templates/accounts/favicon.ico +0 -0
- package/templates/accounts/package.json +0 -48
- package/templates/accounts/src/browser/home.view.tsx +0 -86
- package/templates/accounts/src/browser/index.ts +0 -3
- package/templates/accounts/src/browser/login.view.tsx +0 -78
- package/templates/accounts/src/browser/module.ts +0 -3
- package/templates/accounts/src/common/entity-protocol.ts +0 -7
- package/templates/accounts/src/common/index.ts +0 -1
- package/templates/accounts/src/node/authentication/authentication-success-handler.ts +0 -69
- package/templates/accounts/src/node/authentication/index.ts +0 -1
- package/templates/accounts/src/node/entity/base-entity.ts +0 -13
- package/templates/accounts/src/node/entity/connection.ts +0 -52
- package/templates/accounts/src/node/entity/index.ts +0 -1
- package/templates/accounts/src/node/entity/user.ts +0 -73
- package/templates/accounts/src/node/error/error.ts +0 -14
- package/templates/accounts/src/node/error/index.ts +0 -1
- package/templates/accounts/src/node/index.ts +0 -2
- package/templates/accounts/src/node/module.ts +0 -9
- package/templates/accounts/src/node/user/index.ts +0 -4
- package/templates/accounts/src/node/user/user-protocol.ts +0 -19
- package/templates/accounts/src/node/user/user-repository.ts +0 -72
- package/templates/accounts/src/node/user/user-service.ts +0 -36
- package/templates/accounts/tsconfig.json +0 -32
- package/templates/admin-app/.github/workflows/deploy.yml +0 -25
- package/templates/admin-app/.vscode/launch.json +0 -23
- package/templates/admin-app/README.md +0 -76
- package/templates/admin-app/cell-database.yml +0 -7
- package/templates/admin-app/cell.yml +0 -93
- package/templates/admin-app/package.json +0 -37
- package/templates/admin-app/src/browser/user.view.tsx +0 -40
- package/templates/admin-app/src/common/index.ts +0 -1
- package/templates/admin-app/src/common/user-protocol.ts +0 -23
- package/templates/admin-app/src/node/entity/index.ts +0 -1
- package/templates/admin-app/src/node/entity/user.ts +0 -15
- package/templates/admin-app/src/node/module.ts +0 -8
- package/templates/admin-app/src/node/user-service.ts +0 -41
- package/templates/admin-app/tsconfig.json +0 -32
- package/templates/backend-app/.github/workflows/deploy.yml +0 -25
- package/templates/backend-app/.vscode/launch.json +0 -23
- package/templates/backend-app/README.md +0 -76
- package/templates/backend-app/cell.yml +0 -0
- package/templates/backend-app/package.json +0 -33
- package/templates/backend-app/src/home-controller.ts +0 -11
- package/templates/backend-app/src/module.ts +0 -4
- package/templates/backend-app/src/user-controller.ts +0 -48
- package/templates/backend-app/test/home-controller.spec.ts +0 -19
- package/templates/backend-app/tsconfig.json +0 -32
- package/templates/cell-component/README.md +0 -27
- package/templates/cell-component/cell.yml +0 -0
- package/templates/cell-component/package.json +0 -29
- package/templates/cell-component/src/echo-service.ts +0 -16
- package/templates/cell-component/src/index.ts +0 -1
- package/templates/cell-component/src/package.spec.ts +0 -5
- package/templates/cell-component/tsconfig.json +0 -37
- package/templates/database-app/.github/workflows/deploy.yml +0 -25
- package/templates/database-app/.vscode/launch.json +0 -23
- package/templates/database-app/README.md +0 -76
- package/templates/database-app/cell.yml +0 -17
- package/templates/database-app/package.json +0 -31
- package/templates/database-app/src/entity/index.ts +0 -1
- package/templates/database-app/src/entity/user.ts +0 -13
- package/templates/database-app/src/home-controller.ts +0 -11
- package/templates/database-app/src/module.ts +0 -8
- package/templates/database-app/src/user-controller.ts +0 -43
- package/templates/database-app/tsconfig.json +0 -32
- package/templates/docker-app/.github/workflows/deploy.yml +0 -25
- package/templates/docker-app/.vscode/launch.json +0 -23
- package/templates/docker-app/Dockerfile +0 -27
- package/templates/docker-app/README.md +0 -77
- package/templates/docker-app/cell.yml +0 -0
- package/templates/docker-app/package.json +0 -31
- package/templates/docker-app/src/browser/assets/logo.png +0 -0
- package/templates/docker-app/src/browser/css-shims.d.ts +0 -30
- package/templates/docker-app/src/browser/hello.view.tsx +0 -31
- package/templates/docker-app/src/browser/module.ts +0 -3
- package/templates/docker-app/src/browser/style/hello.module.scss +0 -4
- package/templates/docker-app/src/common/welcome-protocol.ts +0 -5
- package/templates/docker-app/src/node/module.ts +0 -3
- package/templates/docker-app/src/node/welcome-server.ts +0 -9
- package/templates/docker-app/tsconfig.json +0 -33
- package/templates/file-service/.github/workflows/deploy.yml +0 -25
- package/templates/file-service/.vscode/launch.json +0 -23
- package/templates/file-service/README.md +0 -76
- package/templates/file-service/cell.yml +0 -12
- package/templates/file-service/package.json +0 -34
- package/templates/file-service/src/file-controller.ts +0 -47
- package/templates/file-service/tsconfig.json +0 -32
- package/templates/jwt-app/.github/workflows/deploy.yml +0 -25
- package/templates/jwt-app/.vscode/launch.json +0 -23
- package/templates/jwt-app/README.md +0 -76
- package/templates/jwt-app/cell.yml +0 -4
- package/templates/jwt-app/package.json +0 -36
- package/templates/jwt-app/src/context.ts +0 -16
- package/templates/jwt-app/src/error-handler.ts +0 -30
- package/templates/jwt-app/src/error.ts +0 -4
- package/templates/jwt-app/src/home-controller.ts +0 -23
- package/templates/jwt-app/src/index.ts +0 -5
- package/templates/jwt-app/src/jwt-middleware.ts +0 -36
- package/templates/jwt-app/src/module.ts +0 -3
- package/templates/jwt-app/test/home-controller.spec.ts +0 -19
- package/templates/jwt-app/tsconfig.json +0 -32
- package/templates/koa-app/app.js +0 -8
- package/templates/koa-app/package.json +0 -9
- package/templates/microservice/.github/workflows/deploy.yml +0 -28
- package/templates/microservice/.vscode/launch.json +0 -24
- package/templates/microservice/README.md +0 -76
- package/templates/microservice/examples/backend-app/README.md +0 -76
- package/templates/microservice/examples/backend-app/cell-remote.yml +0 -4
- package/templates/microservice/examples/backend-app/cell.yml +0 -3
- package/templates/microservice/examples/backend-app/package.json +0 -32
- package/templates/microservice/examples/backend-app/src/api-controller.ts +0 -31
- package/templates/microservice/examples/backend-app/src/module.ts +0 -3
- package/templates/microservice/examples/backend-app/tsconfig.json +0 -32
- package/templates/microservice/package.json +0 -20
- package/templates/microservice/packages/api/README.md +0 -76
- package/templates/microservice/packages/api/cell.yml +0 -0
- package/templates/microservice/packages/api/package.json +0 -25
- package/templates/microservice/packages/api/src/common/api-protocol.ts +0 -10
- package/templates/microservice/packages/api/src/common/index.ts +0 -1
- package/templates/microservice/packages/api/tsconfig.json +0 -30
- package/templates/microservice/packages/serviceA/.vscode/launch.json +0 -23
- package/templates/microservice/packages/serviceA/README.md +0 -76
- package/templates/microservice/packages/serviceA/cell.yml +0 -6
- package/templates/microservice/packages/serviceA/package.json +0 -29
- package/templates/microservice/packages/serviceA/src/node/module.ts +0 -3
- package/templates/microservice/packages/serviceA/src/node/service-a.ts +0 -9
- package/templates/microservice/packages/serviceA/tsconfig.json +0 -30
- package/templates/microservice/packages/serviceB/README.md +0 -76
- package/templates/microservice/packages/serviceB/cell.yml +0 -5
- package/templates/microservice/packages/serviceB/package.json +0 -29
- package/templates/microservice/packages/serviceB/src/node/module.ts +0 -3
- package/templates/microservice/packages/serviceB/src/node/service-b.ts +0 -9
- package/templates/microservice/packages/serviceB/tsconfig.json +0 -30
- package/templates/microservice/tsconfig.json +0 -32
- package/templates/mycli/.vscode/launch.json +0 -33
- package/templates/mycli/bin/mycli +0 -2
- package/templates/mycli/bin/mycli-deploy +0 -2
- package/templates/mycli/bin/mycli-init +0 -2
- package/templates/mycli/package.json +0 -33
- package/templates/mycli/src/bootstrap.ts +0 -7
- package/templates/mycli/src/constants.ts +0 -1
- package/templates/mycli/src/deploy/deploy-manager.ts +0 -12
- package/templates/mycli/src/deploy/deploy.ts +0 -16
- package/templates/mycli/src/deploy/index.ts +0 -1
- package/templates/mycli/src/index.ts +0 -2
- package/templates/mycli/src/init/index.ts +0 -1
- package/templates/mycli/src/init/init-manager.ts +0 -85
- package/templates/mycli/src/init/init.ts +0 -25
- package/templates/mycli/src/init/templates.ts +0 -3
- package/templates/mycli/src/module.ts +0 -3
- package/templates/mycli/src/mycli.ts +0 -13
- package/templates/mycli/templates/application-template/README.md +0 -0
- package/templates/mycli/tsconfig.json +0 -32
- package/templates/nest-app/.eslintrc.js +0 -25
- package/templates/nest-app/.prettierrc +0 -4
- package/templates/nest-app/README.md +0 -73
- package/templates/nest-app/nest-cli.json +0 -8
- package/templates/nest-app/package.json +0 -69
- package/templates/nest-app/src/app.controller.spec.ts +0 -22
- package/templates/nest-app/src/app.controller.ts +0 -12
- package/templates/nest-app/src/app.module.ts +0 -10
- package/templates/nest-app/src/app.service.ts +0 -8
- package/templates/nest-app/src/main.ts +0 -8
- package/templates/nest-app/test/app.e2e-spec.ts +0 -24
- package/templates/nest-app/test/jest-e2e.json +0 -9
- package/templates/nest-app/tsconfig.build.json +0 -12
- package/templates/nest-app/tsconfig.json +0 -25
- package/templates/nextjs-app/.eslintrc.json +0 -3
- package/templates/nextjs-app/README.md +0 -34
- package/templates/nextjs-app/next.config.js +0 -6
- package/templates/nextjs-app/package.json +0 -20
- package/templates/nextjs-app/pages/_app.js +0 -7
- package/templates/nextjs-app/pages/api/hello.js +0 -5
- package/templates/nextjs-app/pages/index.js +0 -69
- package/templates/nextjs-app/public/favicon.ico +0 -0
- package/templates/nextjs-app/public/vercel.svg +0 -4
- package/templates/nextjs-app/styles/Home.module.css +0 -116
- package/templates/nextjs-app/styles/globals.css +0 -16
- package/templates/sample-app/.github/workflows/deploy.yml +0 -25
- package/templates/sample-app/.vscode/launch.json +0 -23
- package/templates/sample-app/README.md +0 -76
- package/templates/sample-app/cell.yml +0 -0
- package/templates/sample-app/package.json +0 -31
- package/templates/sample-app/src/browser/assets/logo.png +0 -0
- package/templates/sample-app/src/browser/css-shims.d.ts +0 -30
- package/templates/sample-app/src/browser/hello.view.tsx +0 -31
- package/templates/sample-app/src/browser/module.ts +0 -3
- package/templates/sample-app/src/browser/style/hello.module.scss +0 -4
- package/templates/sample-app/src/common/welcome-protocol.ts +0 -5
- package/templates/sample-app/src/node/module.ts +0 -3
- package/templates/sample-app/src/node/welcome-server.ts +0 -9
- package/templates/sample-app/tsconfig.json +0 -32
- package/templates/schedule/.github/workflows/deploy.yml +0 -25
- package/templates/schedule/.vscode/launch.json +0 -23
- package/templates/schedule/README.md +0 -76
- package/templates/schedule/cell.yml +0 -1
- package/templates/schedule/package.json +0 -29
- package/templates/schedule/src/module.ts +0 -3
- package/templates/schedule/src/scheduler.ts +0 -10
- package/templates/schedule/tsconfig.json +0 -32
- package/templates/standalone-app/package.json +0 -17
- package/templates/standalone-app/src/app.service.ts +0 -10
- package/templates/standalone-app/src/main.ts +0 -14
- package/templates/standalone-app/src/module.ts +0 -3
- package/templates/standalone-app/tsconfig.json +0 -30
- package/templates/vue-app/.github/workflows/deploy.yml +0 -25
- package/templates/vue-app/.vscode/launch.json +0 -23
- package/templates/vue-app/README.md +0 -76
- package/templates/vue-app/cell.yml +0 -0
- package/templates/vue-app/package.json +0 -32
- package/templates/vue-app/src/browser/App.vue +0 -32
- package/templates/vue-app/src/browser/app.ts +0 -7
- package/templates/vue-app/src/browser/components/HelloWorld.vue +0 -42
- package/templates/vue-app/src/browser/declare.d.ts +0 -7
- package/templates/vue-app/src/browser/images/logo.png +0 -0
- package/templates/vue-app/src/browser/module.ts +0 -3
- package/templates/vue-app/src/browser/router.ts +0 -13
- package/templates/vue-app/src/browser/shims-vue.d.ts +0 -5
- package/templates/vue-app/src/browser/views/About.vue +0 -5
- package/templates/vue-app/src/browser/views/Root.vue +0 -37
- package/templates/vue-app/src/common/welcome-protocol.ts +0 -5
- package/templates/vue-app/src/node/module.ts +0 -3
- package/templates/vue-app/src/node/welcome-server.ts +0 -9
- package/templates/vue-app/tsconfig.json +0 -32
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { CellError, type DeployContext, type Deployment, type DeployPlan, type DeployResource, defineDeployer } from '@celljs/kit';
|
|
2
|
+
import { CloudApi, CloudApiError, CloudCredentials, type CloudIo, CloudNames, DEFAULT_IO } from '../../deploy/cloud-api.js';
|
|
3
|
+
import { CodePackage } from '../../deploy/code-package.js';
|
|
4
|
+
import { RequestSigner } from '../../deploy/request-signer.js';
|
|
5
|
+
import { ScfPreset } from './scf-preset.js';
|
|
6
|
+
|
|
7
|
+
type Credentials = NonNullable<ReturnType<typeof CloudCredentials.tencent>>;
|
|
8
|
+
|
|
9
|
+
/** Tencent Cloud API 3.0 calls of SCF (version 2018-04-16). */
|
|
10
|
+
export class ScfClient {
|
|
11
|
+
static readonly HOST = 'scf.tencentcloudapi.com';
|
|
12
|
+
static readonly VERSION = '2018-04-16';
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
readonly region: string,
|
|
16
|
+
protected readonly credentials: Credentials,
|
|
17
|
+
protected readonly io: CloudIo = DEFAULT_IO,
|
|
18
|
+
) {}
|
|
19
|
+
|
|
20
|
+
async call<T = Record<string, any>>(action: string, params: Record<string, unknown>): Promise<T> {
|
|
21
|
+
const body = JSON.stringify(params);
|
|
22
|
+
const headers = RequestSigner.tc3(
|
|
23
|
+
{ service: 'scf', host: ScfClient.HOST, action, version: ScfClient.VERSION, region: this.region, body },
|
|
24
|
+
this.credentials,
|
|
25
|
+
this.io.now(),
|
|
26
|
+
);
|
|
27
|
+
const response = await CloudApi.send(this.io, `https://${ScfClient.HOST}/`, { method: 'POST', headers, body }, 'Tencent Cloud SCF');
|
|
28
|
+
const raw = await response.text();
|
|
29
|
+
const json = (raw ? JSON.parse(raw) : {}) as { Response?: Record<string, any> & { Error?: { Code: string; Message: string }; RequestId?: string } };
|
|
30
|
+
const result = json.Response ?? {};
|
|
31
|
+
if (result.Error || !response.ok) {
|
|
32
|
+
throw new CloudApiError(response.status, result.Error?.Code ?? String(response.status), result.Error?.Message ?? raw, result.RequestId);
|
|
33
|
+
}
|
|
34
|
+
return result as T;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async getFunction(name: string, namespace: string): Promise<Record<string, any> | undefined> {
|
|
38
|
+
try {
|
|
39
|
+
return await this.call('GetFunction', { FunctionName: name, Namespace: namespace });
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (error instanceof CloudApiError && error.code.startsWith('ResourceNotFound')) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Deploys the output of the scf preset with the SCF API: a web function (Type HTTP) with the output
|
|
51
|
+
* directory as code, and a public function URL without authentication. Credentials:
|
|
52
|
+
* TENCENTCLOUD_SECRET_ID / TENCENTCLOUD_SECRET_KEY (/ TENCENTCLOUD_SESSION_TOKEN).
|
|
53
|
+
*/
|
|
54
|
+
export class ScfDeployment {
|
|
55
|
+
/** ZipFile of the API: base64 of at most 20 MB. */
|
|
56
|
+
static readonly MAX_PACKAGE = 20 * 1024 * 1024;
|
|
57
|
+
static readonly CREDENTIALS = 'TENCENTCLOUD_SECRET_ID and TENCENTCLOUD_SECRET_KEY';
|
|
58
|
+
static readonly TRIGGER = 'cell-url';
|
|
59
|
+
|
|
60
|
+
readonly name: string;
|
|
61
|
+
readonly region: string;
|
|
62
|
+
readonly namespace: string;
|
|
63
|
+
protected readonly credentials?: Credentials;
|
|
64
|
+
|
|
65
|
+
constructor(
|
|
66
|
+
protected readonly context: DeployContext,
|
|
67
|
+
protected readonly io: CloudIo = DEFAULT_IO,
|
|
68
|
+
) {
|
|
69
|
+
const { options, env, root } = context;
|
|
70
|
+
this.name = CloudNames.functionName(root, options.name, 60);
|
|
71
|
+
this.region = (options.region as string | undefined) ?? env.TENCENTCLOUD_REGION ?? 'ap-guangzhou';
|
|
72
|
+
this.namespace = (options.namespace as string | undefined) ?? 'default';
|
|
73
|
+
this.credentials = CloudCredentials.tencent(env);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
get runtime(): ScfPreset.Runtime {
|
|
77
|
+
return (this.context.options.runtime as ScfPreset.Runtime | undefined) ?? ScfPreset.DEFAULT_RUNTIME;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get settings(): { MemorySize: number; Timeout: number; Environment: { Variables: { Key: string; Value: string }[] } } {
|
|
81
|
+
const { options } = this.context;
|
|
82
|
+
const env = { NODE_ENV: 'production', ...((options.env as Record<string, string> | undefined) ?? {}) };
|
|
83
|
+
return {
|
|
84
|
+
MemorySize: Math.ceil(((options.memory as number | undefined) ?? 512) / 128) * 128,
|
|
85
|
+
Timeout: (options.timeout as number | undefined) ?? 60,
|
|
86
|
+
Environment: { Variables: Object.entries(env).map(([Key, Value]) => ({ Key, Value })) },
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async plan(): Promise<DeployPlan> {
|
|
91
|
+
this.checkOutput();
|
|
92
|
+
const code = CodePackage.of(this.context.outDir);
|
|
93
|
+
let fn: boolean | undefined;
|
|
94
|
+
let url: boolean | undefined;
|
|
95
|
+
if (this.credentials) {
|
|
96
|
+
const client = new ScfClient(this.region, this.credentials, this.io);
|
|
97
|
+
fn = Boolean(await this.step('GetFunction', () => client.getFunction(this.name, this.namespace)));
|
|
98
|
+
url = fn && (await this.urlTrigger(client)) !== undefined;
|
|
99
|
+
} else {
|
|
100
|
+
this.context.warn(`No Tencent Cloud credentials (${ScfDeployment.CREDENTIALS}): the plan does not say whether the function exists.`);
|
|
101
|
+
}
|
|
102
|
+
const action = (found?: boolean): DeployResource['action'] => (found === undefined ? 'deploy' : found ? 'update' : 'create');
|
|
103
|
+
return {
|
|
104
|
+
deployer: 'scf',
|
|
105
|
+
resources: [
|
|
106
|
+
{
|
|
107
|
+
type: 'web-function',
|
|
108
|
+
name: this.name,
|
|
109
|
+
action: action(fn),
|
|
110
|
+
details: {
|
|
111
|
+
region: this.region,
|
|
112
|
+
namespace: this.namespace,
|
|
113
|
+
runtime: this.runtime,
|
|
114
|
+
memorySize: this.settings.MemorySize,
|
|
115
|
+
timeout: this.settings.Timeout,
|
|
116
|
+
package: code.describe(),
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
...(url
|
|
120
|
+
? []
|
|
121
|
+
: [{ type: 'function-url', name: ScfDeployment.TRIGGER, action: action(url), details: { authType: 'NONE' } } satisfies DeployResource]),
|
|
122
|
+
],
|
|
123
|
+
details: { region: this.region, credentials: this.credentials ? 'TENCENTCLOUD_SECRET_ID' : 'missing' },
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async apply(): Promise<Deployment> {
|
|
128
|
+
this.checkOutput();
|
|
129
|
+
if (!this.credentials) {
|
|
130
|
+
throw CloudCredentials.missing('Tencent Cloud', ScfDeployment.CREDENTIALS, ' (an API key of a sub-user with QcloudSCFFullAccess)');
|
|
131
|
+
}
|
|
132
|
+
const client = new ScfClient(this.region, this.credentials, this.io);
|
|
133
|
+
const code = CodePackage.of(this.context.outDir);
|
|
134
|
+
code.checkSize(
|
|
135
|
+
ScfDeployment.MAX_PACKAGE,
|
|
136
|
+
'SCF',
|
|
137
|
+
'Keep large packages out of the server bundle and the output directory, or upload the package with COS from the SCF console.',
|
|
138
|
+
);
|
|
139
|
+
const id = { FunctionName: this.name, Namespace: this.namespace };
|
|
140
|
+
if (await this.step('GetFunction', () => client.getFunction(this.name, this.namespace))) {
|
|
141
|
+
this.context.info(`Updating web function ${this.name} in ${this.region} (${code.describe()})…`);
|
|
142
|
+
await this.waitActive(client);
|
|
143
|
+
await this.step('UpdateFunctionCode', () => client.call('UpdateFunctionCode', { ...id, ZipFile: code.base64, CodeSource: 'ZipFile' }));
|
|
144
|
+
await this.waitActive(client);
|
|
145
|
+
await this.step('UpdateFunctionConfiguration', () =>
|
|
146
|
+
client.call('UpdateFunctionConfiguration', { ...id, Runtime: this.runtime, ...this.settings }),
|
|
147
|
+
);
|
|
148
|
+
} else {
|
|
149
|
+
this.context.info(`Creating web function ${this.name} in ${this.region} (${code.describe()})…`);
|
|
150
|
+
await this.step('CreateFunction', () =>
|
|
151
|
+
client.call('CreateFunction', {
|
|
152
|
+
...id,
|
|
153
|
+
Type: 'HTTP',
|
|
154
|
+
Runtime: this.runtime,
|
|
155
|
+
Code: { ZipFile: code.base64 },
|
|
156
|
+
Description: 'Deployed by Cell (cell deploy --preset scf)',
|
|
157
|
+
...this.settings,
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
await this.waitActive(client);
|
|
162
|
+
let url = await this.urlTrigger(client);
|
|
163
|
+
if (url === undefined) {
|
|
164
|
+
this.context.info('Creating the function URL…');
|
|
165
|
+
await this.step('CreateTrigger', () =>
|
|
166
|
+
client.call('CreateTrigger', {
|
|
167
|
+
...id,
|
|
168
|
+
TriggerName: ScfDeployment.TRIGGER,
|
|
169
|
+
Type: 'http',
|
|
170
|
+
Qualifier: '$DEFAULT',
|
|
171
|
+
TriggerDesc: JSON.stringify({ AuthType: 'NONE', NetConfig: { EnableIntranet: false, EnableExtranet: true } }),
|
|
172
|
+
}),
|
|
173
|
+
);
|
|
174
|
+
url = await this.urlTrigger(client);
|
|
175
|
+
}
|
|
176
|
+
return { url: url || undefined, details: { region: this.region, namespace: this.namespace, function: this.name } };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** The public URL of the function URL trigger: '' when there is one without a URL yet, undefined when there is none. */
|
|
180
|
+
protected async urlTrigger(client: ScfClient): Promise<string | undefined> {
|
|
181
|
+
const { Triggers = [] } = await this.step('ListTriggers', () =>
|
|
182
|
+
client.call<{ Triggers?: Record<string, any>[] }>('ListTriggers', { FunctionName: this.name, Namespace: this.namespace }),
|
|
183
|
+
);
|
|
184
|
+
const trigger = Triggers.find(t => String(t.Type).toLowerCase() === 'http');
|
|
185
|
+
if (!trigger) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
return /https:\/\/[^\s"\\]+/.exec(JSON.stringify(trigger))?.[0] ?? '';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
protected async waitActive(client: ScfClient): Promise<void> {
|
|
192
|
+
const fn = await CloudApi.poll(
|
|
193
|
+
this.io,
|
|
194
|
+
() => this.step('GetFunction', async () => (await client.getFunction(this.name, this.namespace)) ?? {}),
|
|
195
|
+
f => !/ing$/.test(String(f.Status ?? '')),
|
|
196
|
+
`web function ${this.name} to become active`,
|
|
197
|
+
);
|
|
198
|
+
if (fn.Status !== 'Active') {
|
|
199
|
+
const reasons = (fn.StatusReasons as { ErrorMessage?: string }[] | undefined)?.map(r => r.ErrorMessage).join('; ');
|
|
200
|
+
throw new CellError({
|
|
201
|
+
code: 'CELL_DEPLOY_FAILED',
|
|
202
|
+
message: `Web function ${this.name} is ${fn.Status}${reasons ? `: ${reasons}` : ''}.`,
|
|
203
|
+
hint: 'Look at the function in the SCF console (its logs show why scf_bootstrap failed); fix it and deploy again.',
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
protected checkOutput(): void {
|
|
209
|
+
if (this.context.manifest.preset !== 'scf') {
|
|
210
|
+
throw new CellError({
|
|
211
|
+
code: 'CELL_DEPLOY_OUTPUT_MISMATCH',
|
|
212
|
+
message: `${this.context.outDir} has no output of the scf preset (built with: ${this.context.manifest.preset ?? 'no preset'}).`,
|
|
213
|
+
hint: 'Run cell deploy --preset scf without --skip-build, or cell build --preset scf first.',
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
protected async step<T>(name: string, call: () => Promise<T>): Promise<T> {
|
|
219
|
+
try {
|
|
220
|
+
return await call();
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw error instanceof CloudApiError ? CloudApi.failure('SCF', name, error) : error;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export const scfDeployer = defineDeployer({
|
|
228
|
+
name: 'scf',
|
|
229
|
+
description: 'Tencent Cloud SCF through its API (TENCENTCLOUD_SECRET_ID / _KEY)',
|
|
230
|
+
plan: context => new ScfDeployment(context).plan(),
|
|
231
|
+
apply: context => new ScfDeployment(context).apply(),
|
|
232
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { definePreset, type PresetOutputContext } from '@celljs/kit';
|
|
2
|
+
import { PresetOptionsSchema } from '../../deploy/cloud-api.js';
|
|
3
|
+
import { ServerlessScripts } from '../serverless-scripts.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Tencent Cloud SCF web functions: `scf_bootstrap` starts the Cell server with the Node.js of the
|
|
7
|
+
* runtime on port 9000, and a function URL sends requests to it. Only /tmp is writable there.
|
|
8
|
+
*/
|
|
9
|
+
export namespace ScfPreset {
|
|
10
|
+
export const BOOTSTRAP = 'scf_bootstrap';
|
|
11
|
+
export const PORT = 9000;
|
|
12
|
+
export const RUNTIMES = { 'Nodejs18.15': '/var/lang/node18/bin/node', 'Nodejs16.13': '/var/lang/node16/bin/node' } as const;
|
|
13
|
+
export type Runtime = keyof typeof RUNTIMES;
|
|
14
|
+
export const DEFAULT_RUNTIME: Runtime = 'Nodejs18.15';
|
|
15
|
+
|
|
16
|
+
export const OPTIONS = PresetOptionsSchema.of({
|
|
17
|
+
name: 'string',
|
|
18
|
+
region: 'string',
|
|
19
|
+
namespace: 'string',
|
|
20
|
+
runtime: Object.keys(RUNTIMES),
|
|
21
|
+
memory: 'number',
|
|
22
|
+
timeout: 'number',
|
|
23
|
+
env: 'env',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export function output(context: PresetOutputContext): void {
|
|
27
|
+
const { manifest, options } = context;
|
|
28
|
+
if (!manifest.server) {
|
|
29
|
+
context.warn('The scf preset deploys a server, but the project builds no backend.');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const node = RUNTIMES[(options.runtime as Runtime | undefined) ?? DEFAULT_RUNTIME];
|
|
33
|
+
context.write(BOOTSTRAP, ServerlessScripts.bootstrap({ preset: 'scf', node, port: PORT, server: manifest.server }), 0o755);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const scfPreset = definePreset({
|
|
38
|
+
name: 'scf',
|
|
39
|
+
description: 'Tencent Cloud SCF web function (function URL)',
|
|
40
|
+
entry: 'http',
|
|
41
|
+
format: 'esm',
|
|
42
|
+
options: ScfPreset.OPTIONS,
|
|
43
|
+
output: context => ScfPreset.output(context),
|
|
44
|
+
deployer: 'scf',
|
|
45
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/** What the generated scripts of the serverless presets need. */
|
|
2
|
+
export interface BootstrapOptions {
|
|
3
|
+
preset: string;
|
|
4
|
+
/** Node.js of the platform's image; `node` from PATH is used when it is not there (local runs). */
|
|
5
|
+
node: string;
|
|
6
|
+
/** Port the platform sends requests to; `portVariable` overrides it when the platform sets one. */
|
|
7
|
+
port: number;
|
|
8
|
+
portVariable?: string;
|
|
9
|
+
/** Server bundle, relative to the output directory. */
|
|
10
|
+
server: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Start scripts and handlers around the server bundle for function platforms. Each runs the Cell
|
|
15
|
+
* server unchanged: FC and SCF start it as a web server on their port; Lambda and Vercel hand it
|
|
16
|
+
* requests in process through the application host (`Symbol.for('@celljs/core/application-host')`).
|
|
17
|
+
*/
|
|
18
|
+
export namespace ServerlessScripts {
|
|
19
|
+
const HOST_KEY = "Symbol.for('@celljs/core/application-host')";
|
|
20
|
+
const NO_HTTP = 'The application has no HTTP entry: add @celljs/express-adapter to the dependencies.';
|
|
21
|
+
|
|
22
|
+
/** A bash start script for FC custom runtimes and SCF web functions, run from the code directory. */
|
|
23
|
+
export function bootstrap({ preset, node, port, portVariable, server }: BootstrapOptions): string {
|
|
24
|
+
const portValue = portVariable ? `\${${portVariable}:-${port}}` : String(port);
|
|
25
|
+
return [
|
|
26
|
+
'#!/bin/bash',
|
|
27
|
+
`# Generated by the Cell ${preset} preset. Do not edit.`,
|
|
28
|
+
'cd "$(dirname "$0")" || exit 1',
|
|
29
|
+
`NODE=${node}`,
|
|
30
|
+
'[ -x "$NODE" ] || NODE=node',
|
|
31
|
+
'export NODE_ENV="${NODE_ENV:-production}"',
|
|
32
|
+
// The platform forwards requests to this port on all interfaces.
|
|
33
|
+
'export CELL_BACKEND__SERVER__HOST=0.0.0.0',
|
|
34
|
+
`export CELL_BACKEND__SERVER__PORT="${portValue}"`,
|
|
35
|
+
`exec "$NODE" ${server}`,
|
|
36
|
+
'',
|
|
37
|
+
].join('\n');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* `server/lambda.mjs`: the Lambda handler. The application serves HTTP on a loopback port during
|
|
42
|
+
* the init phase; each function URL / API Gateway HTTP API (payload 2.0) event becomes a request
|
|
43
|
+
* to it, and the response comes back base64-encoded.
|
|
44
|
+
*/
|
|
45
|
+
export const LAMBDA_HANDLER = [
|
|
46
|
+
'// Generated by the Cell lambda preset. Do not edit.',
|
|
47
|
+
"import { createServer, request } from 'node:http';",
|
|
48
|
+
"import { fileURLToPath } from 'node:url';",
|
|
49
|
+
'',
|
|
50
|
+
"process.env.NODE_ENV ??= 'production';",
|
|
51
|
+
'// The package root: public/ (the frontend) is there.',
|
|
52
|
+
"process.chdir(fileURLToPath(new URL('..', import.meta.url)));",
|
|
53
|
+
'const server = createServer();',
|
|
54
|
+
'const application = new Promise((resolve, reject) => {',
|
|
55
|
+
` globalThis[${HOST_KEY}] = {`,
|
|
56
|
+
' server,',
|
|
57
|
+
' started: app => {',
|
|
58
|
+
' if (!app.handler) {',
|
|
59
|
+
` reject(new Error('${NO_HTTP}'));`,
|
|
60
|
+
' return;',
|
|
61
|
+
' }',
|
|
62
|
+
" server.on('request', app.handler);",
|
|
63
|
+
' resolve();',
|
|
64
|
+
' },',
|
|
65
|
+
' failed: reject,',
|
|
66
|
+
' };',
|
|
67
|
+
'});',
|
|
68
|
+
"await import('./index.mjs');",
|
|
69
|
+
'await application;',
|
|
70
|
+
"await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));",
|
|
71
|
+
'const { port } = server.address();',
|
|
72
|
+
'',
|
|
73
|
+
'export async function handler(event) {',
|
|
74
|
+
" const method = event.requestContext?.http?.method ?? event.httpMethod ?? 'GET';",
|
|
75
|
+
" const path = event.rawPath ?? event.path ?? '/';",
|
|
76
|
+
" const query = event.rawQueryString ?? '';",
|
|
77
|
+
' const headers = { ...event.headers };',
|
|
78
|
+
' if (event.cookies?.length) {',
|
|
79
|
+
" headers.cookie = event.cookies.join('; ');",
|
|
80
|
+
' }',
|
|
81
|
+
" delete headers['transfer-encoding'];",
|
|
82
|
+
" const body = event.body == null ? undefined : Buffer.from(event.body, event.isBase64Encoded ? 'base64' : 'utf8');",
|
|
83
|
+
' if (body) {',
|
|
84
|
+
" headers['content-length'] = String(body.length);",
|
|
85
|
+
' }',
|
|
86
|
+
' const { res, data } = await new Promise((resolve, reject) => {',
|
|
87
|
+
" const req = request({ host: '127.0.0.1', port, method, path: query ? `${path}?${query}` : path, headers }, res => {",
|
|
88
|
+
' const chunks = [];',
|
|
89
|
+
" res.on('data', chunk => chunks.push(chunk));",
|
|
90
|
+
" res.on('end', () => resolve({ res, data: Buffer.concat(chunks) }));",
|
|
91
|
+
" res.on('error', reject);",
|
|
92
|
+
' });',
|
|
93
|
+
" req.on('error', reject);",
|
|
94
|
+
' req.end(body);',
|
|
95
|
+
' });',
|
|
96
|
+
' const responseHeaders = {};',
|
|
97
|
+
' let cookies = [];',
|
|
98
|
+
' for (const [name, value] of Object.entries(res.headers)) {',
|
|
99
|
+
" if (name === 'set-cookie') {",
|
|
100
|
+
' cookies = value;',
|
|
101
|
+
' } else {',
|
|
102
|
+
" responseHeaders[name] = Array.isArray(value) ? value.join(', ') : value;",
|
|
103
|
+
' }',
|
|
104
|
+
' }',
|
|
105
|
+
" return { statusCode: res.statusCode, headers: responseHeaders, cookies, body: data.toString('base64'), isBase64Encoded: true };",
|
|
106
|
+
'}',
|
|
107
|
+
'',
|
|
108
|
+
].join('\n');
|
|
109
|
+
|
|
110
|
+
/** `functions/index.func/vercel.mjs`: a Vercel Node.js function that hands each request to the application. */
|
|
111
|
+
export const VERCEL_FUNCTION = [
|
|
112
|
+
'// Generated by the Cell vercel preset. Do not edit.',
|
|
113
|
+
"import { fileURLToPath } from 'node:url';",
|
|
114
|
+
'',
|
|
115
|
+
"process.env.NODE_ENV ??= 'production';",
|
|
116
|
+
'// The function directory: public/index.html (the single-page fallback) is there.',
|
|
117
|
+
"process.chdir(fileURLToPath(new URL('.', import.meta.url)));",
|
|
118
|
+
'const application = new Promise((resolve, reject) => {',
|
|
119
|
+
` globalThis[${HOST_KEY}] = {`,
|
|
120
|
+
` started: app => (app.handler ? resolve(app.handler) : reject(new Error('${NO_HTTP}'))),`,
|
|
121
|
+
' failed: reject,',
|
|
122
|
+
' };',
|
|
123
|
+
'});',
|
|
124
|
+
"await import('./server/index.mjs');",
|
|
125
|
+
'const handler = await application;',
|
|
126
|
+
'',
|
|
127
|
+
'export default function cell(req, res) {',
|
|
128
|
+
' handler(req, res);',
|
|
129
|
+
'}',
|
|
130
|
+
'',
|
|
131
|
+
].join('\n');
|
|
132
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
4
|
+
import { stripVTControlCharacters } from 'node:util';
|
|
5
|
+
import { CellError, type DeployContext, type Deployment, type DeployPlan, defineDeployer } from '@celljs/kit';
|
|
6
|
+
import { CloudNames } from '../../deploy/cloud-api.js';
|
|
7
|
+
import { VercelPreset } from './vercel-preset.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Runs the Vercel CLI, which uploads prebuilt outputs and owns the credentials (`VERCEL_TOKEN` or
|
|
11
|
+
* `vercel login`). Like Wrangler it is not a dependency: the project's is used, else npx installs
|
|
12
|
+
* {@link VercelCli.PACKAGE} on first use.
|
|
13
|
+
*/
|
|
14
|
+
export class VercelCli {
|
|
15
|
+
static readonly PACKAGE = 'vercel@65';
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
protected readonly root: string,
|
|
19
|
+
protected readonly env: NodeJS.ProcessEnv,
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
command(args: string[]): { command: string; args: string[]; source: 'project' | 'npx' } {
|
|
23
|
+
for (let dir = this.root; ; dir = dirname(dir)) {
|
|
24
|
+
const manifest = join(dir, 'node_modules', 'vercel', 'package.json');
|
|
25
|
+
if (existsSync(manifest)) {
|
|
26
|
+
const { bin } = JSON.parse(readFileSync(manifest, 'utf8')) as { bin?: Record<string, string> };
|
|
27
|
+
if (bin?.vercel) {
|
|
28
|
+
return {
|
|
29
|
+
command: process.execPath.includes('bun') ? 'node' : process.execPath,
|
|
30
|
+
args: [join(dirname(manifest), bin.vercel), ...args],
|
|
31
|
+
source: 'project',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (dirname(dir) === dir) {
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { command: process.platform === 'win32' ? 'npx.cmd' : 'npx', args: ['--yes', VercelCli.PACKAGE, ...args], source: 'npx' };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
run(args: string[], relay: (chunk: string, stream: 'stdout' | 'stderr') => void): Promise<{ code: number; output: string; source: 'project' | 'npx' }> {
|
|
43
|
+
const { command, args: commandArgs, source } = this.command(args);
|
|
44
|
+
return new Promise((done, reject) => {
|
|
45
|
+
let output = '';
|
|
46
|
+
const child = spawn(command, commandArgs, { cwd: this.root, env: this.env, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
47
|
+
for (const stream of ['stdout', 'stderr'] as const) {
|
|
48
|
+
child[stream].setEncoding('utf8');
|
|
49
|
+
child[stream].on('data', (chunk: string) => {
|
|
50
|
+
output += chunk;
|
|
51
|
+
relay(chunk, stream);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
child.on('error', reject);
|
|
55
|
+
child.on('close', code => done({ code: code ?? 1, output: stripVTControlCharacters(output), source }));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static isAuthError(output: string): boolean {
|
|
60
|
+
return /no existing credentials|not logged in|vercel login|invalid token|token is not valid|missing.*token|authentication/i.test(output);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The last line Vercel printed with `Error`, else its last line. */
|
|
64
|
+
static errorOf(output: string): string {
|
|
65
|
+
const lines = output
|
|
66
|
+
.split('\n')
|
|
67
|
+
.map(l => l.trim())
|
|
68
|
+
.filter(Boolean);
|
|
69
|
+
return lines.filter(l => /error/i.test(l)).pop() ?? lines.pop() ?? 'The Vercel CLI failed without output.';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Deploys `.vercel/output` with `vercel deploy --prebuilt`: no build runs on Vercel. */
|
|
74
|
+
export class VercelDeployment {
|
|
75
|
+
readonly project: string;
|
|
76
|
+
protected readonly cli: VercelCli;
|
|
77
|
+
|
|
78
|
+
constructor(protected readonly context: DeployContext) {
|
|
79
|
+
this.project = CloudNames.functionName(context.root, context.options.project, 100);
|
|
80
|
+
this.cli = new VercelCli(context.root, context.env);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get production(): boolean {
|
|
84
|
+
return (this.context.options.environment ?? 'production') === 'production';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async plan(): Promise<DeployPlan> {
|
|
88
|
+
this.checkOutput();
|
|
89
|
+
const { outDir, manifest, env, options } = this.context;
|
|
90
|
+
const config = JSON.parse(readFileSync(join(outDir, VercelPreset.FUNCTION, '.vc-config.json'), 'utf8').toString()) as { runtime: string };
|
|
91
|
+
const staticFiles = manifest.public ? (readdirSync(join(outDir, manifest.public), { recursive: true }) as string[]).length : 0;
|
|
92
|
+
return {
|
|
93
|
+
deployer: 'vercel',
|
|
94
|
+
resources: [
|
|
95
|
+
{
|
|
96
|
+
type: 'deployment',
|
|
97
|
+
name: this.project,
|
|
98
|
+
action: 'deploy',
|
|
99
|
+
details: {
|
|
100
|
+
environment: this.production ? 'production' : 'preview',
|
|
101
|
+
...(options.scope ? { scope: options.scope } : {}),
|
|
102
|
+
function: `index (${config.runtime})`,
|
|
103
|
+
staticFiles,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
details: {
|
|
108
|
+
output: relative(this.context.root, outDir),
|
|
109
|
+
cli: this.cli.command([]).source === 'project' ? 'project' : VercelCli.PACKAGE,
|
|
110
|
+
credentials: env.VERCEL_TOKEN ? 'VERCEL_TOKEN' : 'vercel login',
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async apply(): Promise<Deployment> {
|
|
116
|
+
this.checkOutput();
|
|
117
|
+
const { env, options } = this.context;
|
|
118
|
+
const args = [
|
|
119
|
+
'deploy',
|
|
120
|
+
'--prebuilt',
|
|
121
|
+
'--yes',
|
|
122
|
+
'--project',
|
|
123
|
+
this.project,
|
|
124
|
+
'--create-if-missing',
|
|
125
|
+
...(this.production ? ['--prod'] : []),
|
|
126
|
+
...(options.scope ? ['--scope', String(options.scope)] : []),
|
|
127
|
+
...(env.VERCEL_TOKEN ? ['--token', env.VERCEL_TOKEN] : []),
|
|
128
|
+
];
|
|
129
|
+
this.context.info(`Deploying ${this.project} with vercel deploy --prebuilt…`);
|
|
130
|
+
const result = await this.cli.run(args, (chunk, stream) => this.context.relay(chunk, stream));
|
|
131
|
+
if (result.code !== 0) {
|
|
132
|
+
throw new CellError({
|
|
133
|
+
code: VercelCli.isAuthError(result.output) ? 'CELL_DEPLOY_UNAUTHORIZED' : 'CELL_DEPLOY_FAILED',
|
|
134
|
+
message: `vercel deploy failed: ${VercelCli.errorOf(result.output)}`,
|
|
135
|
+
hint: VercelCli.isAuthError(result.output)
|
|
136
|
+
? 'Set VERCEL_TOKEN (a token from vercel.com/account/tokens; vercel.scope for a team), or run npx vercel login once.'
|
|
137
|
+
: 'Fix the reported problem (the Vercel CLI printed the details above), then run cell deploy again.',
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const urls = result.output.match(/https:\/\/[\w.-]+\.vercel\.app\b/g) ?? [];
|
|
141
|
+
return { url: urls.pop(), details: { project: this.project, environment: this.production ? 'production' : 'preview' } };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
protected checkOutput(): void {
|
|
145
|
+
const { manifest, outDir, root } = this.context;
|
|
146
|
+
if (manifest.preset !== 'vercel') {
|
|
147
|
+
throw new CellError({
|
|
148
|
+
code: 'CELL_DEPLOY_OUTPUT_MISMATCH',
|
|
149
|
+
message: `${outDir} has no output of the vercel preset (built with: ${manifest.preset ?? 'no preset'}).`,
|
|
150
|
+
hint: 'Run cell deploy --preset vercel without --skip-build, or cell build --preset vercel first.',
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (resolve(outDir) !== resolve(root, VercelPreset.OUT_DIR)) {
|
|
154
|
+
throw new CellError({
|
|
155
|
+
code: 'CELL_DEPLOY_OUTPUT_MISMATCH',
|
|
156
|
+
message: `vercel deploy --prebuilt reads .vercel/output, but the output is in ${relative(root, outDir)}.`,
|
|
157
|
+
hint: 'Build without --out-dir (the vercel preset writes to .vercel/output).',
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const vercelDeployer = defineDeployer({
|
|
164
|
+
name: 'vercel',
|
|
165
|
+
description: "Vercel through vercel deploy --prebuilt (the project's CLI, or vercel@65 installed on first use)",
|
|
166
|
+
plan: context => new VercelDeployment(context).plan(),
|
|
167
|
+
apply: context => new VercelDeployment(context).apply(),
|
|
168
|
+
});
|