UNPKG

create-cloudflare

Version:

A CLI for creating and deploying new applications to Cloudflare.

121 lines (106 loc) 3.4 kB
import { existsSync } from "node:fs"; import { cp, mkdtemp } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { brandColor, dim } from "@cloudflare/cli/colors"; import { processArgument } from "helpers/args"; import { runCommand } from "helpers/command"; import { detectPackageManager } from "helpers/packageManagers"; import { chooseAccount, wranglerLogin } from "../../src/wrangler/accounts"; import type { TemplateConfig } from "../../src/templates"; import type { C3Context } from "types"; export async function copyExistingWorkerFiles(ctx: C3Context) { const { dlx } = detectPackageManager(); if (ctx.args.existingScript === undefined) { ctx.args.existingScript = await processArgument( ctx.args, "existingScript", { type: "text", question: "Please specify the name of the existing worker in this account?", label: "worker", defaultValue: ctx.project.name, }, ); } // `wrangler init --from-dash` bails if you opt-out of creating a package.json // so run it (with -y) in a tempdir and copy the src files after const tempdir = await mkdtemp(join(tmpdir(), "c3-wrangler-init--from-dash-")); await runCommand( [ ...dlx, "wrangler@latest", "init", "--from-dash", ctx.args.existingScript, "-y", "--no-delegate-c3", ], { silent: true, cwd: tempdir, // use a tempdir because we don't want all the files env: { CLOUDFLARE_ACCOUNT_ID: ctx.account?.id }, startText: "Downloading existing worker files", doneText: `${brandColor("downloaded")} ${dim( `existing "${ctx.args.existingScript}" worker files`, )}`, }, ); // copy src/* files from the downloaded Worker await cp( join(tempdir, ctx.args.existingScript, "src"), join(ctx.project.path, "src"), { recursive: true }, ); // copy wrangler config file from the downloaded Worker const configFiles = ["wrangler.jsonc", "wrangler.json", "wrangler.toml"]; let configFileCopied = false; for (const configFile of configFiles) { const sourcePath = join(tempdir, ctx.args.existingScript, configFile); if (existsSync(sourcePath)) { await cp(sourcePath, join(ctx.project.path, configFile)); configFileCopied = true; break; } } if (!configFileCopied) { throw new Error( `No wrangler configuration file found in downloaded worker. Expected one of: ${configFiles.join(", ")}`, ); } } const config: TemplateConfig = { configVersion: 1, id: "pre-existing", displayName: "Pre-existing Worker (from Dashboard)", description: "Fetch a Worker initialized from the Cloudflare dashboard.", platform: "workers", hidden: true, copyFiles: { path: "./js", }, configure: buildConfigure({ login: wranglerLogin, chooseAccount, copyFiles: copyExistingWorkerFiles, }), }; export default config; export interface ConfigureParams { login: (ctx: C3Context) => Promise<boolean>; chooseAccount: (ctx: C3Context) => Promise<void>; copyFiles: (ctx: C3Context) => Promise<void>; } export function buildConfigure(params: ConfigureParams) { return async function configure(ctx: C3Context) { const loginSuccess = await params.login(ctx); if (!loginSuccess) { throw new Error("Failed to login to Cloudflare"); } await params.chooseAccount(ctx); await params.copyFiles(ctx); // Force no-deploy since the Worker is already deployed ctx.args.deploy = false; }; }