Files
bknd/app/src/cli/commands/create/templates/cloudflare.ts
T

167 lines
4.0 KiB
TypeScript

import * as $p from "@clack/prompts";
import { overrideJson } from "cli/commands/create/npm";
import { typewriter } from "cli/utils/cli";
import c from "picocolors";
import type { Template, TemplateSetupCtx } from ".";
import { exec } from "cli/utils/sys";
const WRANGLER_FILE = "wrangler.json";
export const cloudflare = {
key: "cloudflare",
title: "Cloudflare Basic",
integration: "cloudflare",
description: "A basic bknd Cloudflare worker",
path: "gh:bknd-io/bknd/examples/cloudflare-worker",
ref: true,
setup: async (ctx) => {
// overwrite assets directory & name
await overrideJson(
WRANGLER_FILE,
(json) => ({
...json,
name: ctx.name,
assets: {
directory: "node_modules/bknd/dist/static",
},
}),
{ dir: ctx.dir },
);
try {
await createD1(ctx);
} catch (e) {
const message = (e as any).message || "An error occurred";
$p.log.warn(
"Couldn't add database. You can add it manually later. Error: " + c.red(message),
);
}
try {
await createR2(ctx);
} catch (e) {
const message = (e as any).message || "An error occurred";
$p.log.warn(
"Couldn't add R2 bucket. You can add it manually later. Error: " + c.red(message),
);
}
},
} as const satisfies Template;
async function createD1(ctx: TemplateSetupCtx) {
const default_db = "data";
const name = ctx.skip
? default_db
: await $p.text({
message: "Enter database name",
initialValue: default_db,
placeholder: default_db,
validate: (v) => {
if (!v) {
return "Invalid name";
}
return;
},
});
if ($p.isCancel(name)) {
process.exit(1);
}
await $p.stream.info(
(async function* () {
yield* typewriter("Now running wrangler to create a D1 database...");
})(),
);
await overrideJson(
WRANGLER_FILE,
(json) => ({
...json,
d1_databases: [
{
binding: "DB",
database_name: name,
database_id: "00000000-0000-0000-0000-000000000000",
},
],
}),
{ dir: ctx.dir },
);
if (!ctx.skip) {
exec(`npx wrangler d1 create ${name}`);
await $p.stream.info(
(async function* () {
yield* typewriter("Please update your wrangler configuration with the output above.");
})(),
);
}
}
async function createR2(ctx: TemplateSetupCtx) {
const create = ctx.skip
? false
: await $p.confirm({
message: "Do you want to use a R2 bucket?",
initialValue: true,
});
if ($p.isCancel(create)) {
process.exit(1);
}
if (!create) {
await overrideJson(
WRANGLER_FILE,
(json) => ({
...json,
r2_buckets: undefined,
}),
{ dir: ctx.dir },
);
return;
}
const default_bucket = "bucket";
const name = ctx.skip
? default_bucket
: await $p.text({
message: "Enter bucket name",
initialValue: default_bucket,
placeholder: default_bucket,
validate: (v) => {
if (!v) {
return "Invalid name";
}
return;
},
});
if ($p.isCancel(name)) {
process.exit(1);
}
await $p.stream.info(
(async function* () {
yield* typewriter("Now running wrangler to create a R2 bucket...");
})(),
);
await overrideJson(
WRANGLER_FILE,
(json) => ({
...json,
r2_buckets: [
{
binding: "BUCKET",
bucket_name: name,
},
],
}),
{ dir: ctx.dir },
);
if (!ctx.skip) {
exec(`npx wrangler r2 bucket create ${name}`);
}
}