diff --git a/.changeset/hot-ads-return.md b/.changeset/hot-ads-return.md new file mode 100644 index 000000000000..1c35251e8211 --- /dev/null +++ b/.changeset/hot-ads-return.md @@ -0,0 +1,5 @@ +--- +"create-cloudflare": minor +--- + +feature: Add support for wrangler.json(c) in templates diff --git a/packages/create-cloudflare/e2e-tests/cli.test.ts b/packages/create-cloudflare/e2e-tests/cli.test.ts index 7efce879f3b4..21c4d31760d9 100644 --- a/packages/create-cloudflare/e2e-tests/cli.test.ts +++ b/packages/create-cloudflare/e2e-tests/cli.test.ts @@ -217,6 +217,30 @@ describe.skipIf(experimental || frameworkToTest || isQuarantineMode())( }, ); + test({ experimental }).skipIf(process.platform === "win32")( + "Cloning remote template that uses wrangler.json", + async ({ logStream, project }) => { + const { output } = await runC3( + [ + project.path, + "--template=cloudflare/templates/multiplayer-globe-template", + "--no-deploy", + "--git=false", + ], + [], + logStream, + ); + + expect(output).toContain( + `repository cloudflare/templates/multiplayer-globe-template`, + ); + expect(output).toContain( + `Cloning template from: cloudflare/templates/multiplayer-globe-template`, + ); + expect(output).toContain(`template cloned and validated`); + }, + ); + test({ experimental }).skipIf(process.platform === "win32")( "Inferring the category, type and language if the type is `hello-world-python`", async ({ logStream, project }) => { diff --git a/packages/create-cloudflare/src/deploy.ts b/packages/create-cloudflare/src/deploy.ts index 3fd7d7ea08bd..5ebcbb0dfaee 100644 --- a/packages/create-cloudflare/src/deploy.ts +++ b/packages/create-cloudflare/src/deploy.ts @@ -10,9 +10,14 @@ import { quoteShellArgs, runCommand } from "helpers/command"; import { readFile } from "helpers/files"; import { detectPackageManager } from "helpers/packageManagers"; import { poll } from "helpers/poll"; +import { parse as jsoncParse } from "jsonc-parser"; import { isInsideGitRepo } from "./git"; import { chooseAccount, wranglerLogin } from "./wrangler/accounts"; -import { readWranglerToml } from "./wrangler/config"; +import { + readWranglerJson, + readWranglerToml, + wranglerJsonExists, +} from "./wrangler/config"; import type { C3Context } from "types"; export const offerToDeploy = async (ctx: C3Context) => { @@ -72,12 +77,17 @@ const isDeployable = async (ctx: C3Context) => { if (ctx.template.platform === "pages") { return true; } + const wranglerConfig = readWranglerConfig(ctx); + return !hasBinding(wranglerConfig); +}; +const readWranglerConfig = (ctx: C3Context) => { + if (wranglerJsonExists(ctx)) { + const wranglerJsonStr = readWranglerJson(ctx); + return jsoncParse(wranglerJsonStr); + } const wranglerTomlStr = readWranglerToml(ctx); - - const wranglerToml = TOML.parse(wranglerTomlStr.replace(/\r\n/g, "\n")); - - return !hasBinding(wranglerToml); + return TOML.parse(wranglerTomlStr.replace(/\r\n/g, "\n")); }; export const runDeploy = async (ctx: C3Context) => { diff --git a/packages/create-cloudflare/src/templates.ts b/packages/create-cloudflare/src/templates.ts index 648aca91cbec..ace78c71acde 100644 --- a/packages/create-cloudflare/src/templates.ts +++ b/packages/create-cloudflare/src/templates.ts @@ -632,9 +632,15 @@ const validateTemplate = (path: string, config: TemplateConfig) => { const validateTemplateSrcDirectory = (path: string, config: TemplateConfig) => { if (config.platform === "workers") { const wranglerTomlPath = resolve(path, "wrangler.toml"); - if (!existsSync(wranglerTomlPath)) { + const wranglerJsonPath = resolve(path, "wrangler.json"); + const wranglerJsoncPath = resolve(path, "wrangler.jsonc"); + if ( + !existsSync(wranglerTomlPath) && + !existsSync(wranglerJsonPath) && + !existsSync(wranglerJsoncPath) + ) { throw new Error( - `create-cloudflare templates must contain a "wrangler.toml" file.`, + `create-cloudflare templates must contain a "wrangler.toml" or "wrangler.json(c)" file.`, ); } } diff --git a/packages/create-cloudflare/src/wrangler/config.ts b/packages/create-cloudflare/src/wrangler/config.ts index fc54fccf3a55..dbf489e84bf6 100644 --- a/packages/create-cloudflare/src/wrangler/config.ts +++ b/packages/create-cloudflare/src/wrangler/config.ts @@ -49,16 +49,39 @@ const getWranglerTomlPath = (ctx: C3Context) => { return resolve(ctx.project.path, "wrangler.toml"); }; +const getWranglerJsonPath = (ctx: C3Context) => { + return resolve(ctx.project.path, "wrangler.json"); +}; + +const getWranglerJsoncPath = (ctx: C3Context) => { + return resolve(ctx.project.path, "wrangler.jsonc"); +}; + export const wranglerTomlExists = (ctx: C3Context) => { const wranglerTomlPath = getWranglerTomlPath(ctx); return existsSync(wranglerTomlPath); }; +export const wranglerJsonExists = (ctx: C3Context) => { + const wranglerJsonPath = getWranglerJsonPath(ctx); + const wranglerJsoncPath = getWranglerJsoncPath(ctx); + return existsSync(wranglerJsonPath) || existsSync(wranglerJsoncPath); +}; + export const readWranglerToml = (ctx: C3Context) => { const wranglerTomlPath = getWranglerTomlPath(ctx); return readFile(wranglerTomlPath); }; +export const readWranglerJson = (ctx: C3Context) => { + const wranglerJsonPath = getWranglerJsonPath(ctx); + if (existsSync(wranglerJsonPath)) { + return readFile(wranglerJsonPath); + } + const wranglerJsoncPath = getWranglerJsoncPath(ctx); + return readFile(wranglerJsoncPath); +}; + export const writeWranglerToml = (ctx: C3Context, contents: string) => { const wranglerTomlPath = getWranglerTomlPath(ctx); return writeFile(wranglerTomlPath, contents);