create-kide-app 0.0.17 → 0.0.18
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/index.js +70 -22
- package/package.json +1 -1
- package/templates/cloudflare/drizzle.config.ts +12 -6
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import * as p from "@clack/prompts";
|
|
4
|
-
import { execSync } from "node:child_process";
|
|
4
|
+
import { execSync, spawn } from "node:child_process";
|
|
5
5
|
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -9,6 +9,24 @@ import { fileURLToPath } from "node:url";
|
|
|
9
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
const TEMPLATES_DIR = path.join(__dirname, "templates");
|
|
11
11
|
|
|
12
|
+
// Async spawn wrapper so long-running commands don't block clack spinners
|
|
13
|
+
const runAsync = (cmd, cwd) =>
|
|
14
|
+
new Promise((resolve, reject) => {
|
|
15
|
+
const child = spawn(cmd, { cwd, shell: true });
|
|
16
|
+
let stdout = "";
|
|
17
|
+
let stderr = "";
|
|
18
|
+
child.stdout.on("data", (d) => (stdout += d.toString()));
|
|
19
|
+
child.stderr.on("data", (d) => (stderr += d.toString()));
|
|
20
|
+
child.on("close", (code) => {
|
|
21
|
+
if (code === 0) resolve(stdout);
|
|
22
|
+
else {
|
|
23
|
+
const err = new Error(`Command failed: ${cmd}`);
|
|
24
|
+
err.stderr = stderr;
|
|
25
|
+
reject(err);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
12
30
|
// --- Package manager detection ---
|
|
13
31
|
|
|
14
32
|
const pm = { name: "pnpm", exec: "pnpm dlx", run: "pnpm", install: "pnpm install" };
|
|
@@ -150,7 +168,7 @@ async function main() {
|
|
|
150
168
|
|
|
151
169
|
s.start("Installing dependencies");
|
|
152
170
|
try {
|
|
153
|
-
|
|
171
|
+
await runAsync(pm.install, projectDir);
|
|
154
172
|
s.stop("Dependencies installed");
|
|
155
173
|
} catch {
|
|
156
174
|
s.stop(`${pm.install} failed — run it manually`);
|
|
@@ -199,7 +217,7 @@ async function main() {
|
|
|
199
217
|
|
|
200
218
|
// --- Cloudflare resource setup ---
|
|
201
219
|
|
|
202
|
-
const cf = { d1Created: false, r2Created: false, migrationsApplied: false };
|
|
220
|
+
const cf = { d1Created: false, r2Created: false, migrationsApplied: false, deployed: false, url: null };
|
|
203
221
|
if (target === "cloudflare") {
|
|
204
222
|
const setupNow = await p.confirm({
|
|
205
223
|
message: "Set up Cloudflare resources now? (creates D1 database and R2 bucket)",
|
|
@@ -299,6 +317,7 @@ async function main() {
|
|
|
299
317
|
execSync(`${pm.exec} wrangler d1 migrations apply ${projectName}-db --remote`, {
|
|
300
318
|
cwd: projectDir,
|
|
301
319
|
stdio: "pipe",
|
|
320
|
+
input: "y\n",
|
|
302
321
|
});
|
|
303
322
|
cf.migrationsApplied = true;
|
|
304
323
|
s.stop("Migrations applied");
|
|
@@ -306,6 +325,27 @@ async function main() {
|
|
|
306
325
|
s.stop("Migration apply failed — run manually with: wrangler d1 migrations apply --remote");
|
|
307
326
|
}
|
|
308
327
|
}
|
|
328
|
+
|
|
329
|
+
// Deploy to Cloudflare
|
|
330
|
+
if (cf.migrationsApplied) {
|
|
331
|
+
const doDeploy = await p.confirm({
|
|
332
|
+
message: "Deploy to Cloudflare now?",
|
|
333
|
+
initialValue: true,
|
|
334
|
+
});
|
|
335
|
+
if (!p.isCancel(doDeploy) && doDeploy) {
|
|
336
|
+
s.start("Building and deploying to Cloudflare");
|
|
337
|
+
try {
|
|
338
|
+
const deployOutput = await runAsync(`${pm.run} deploy`, projectDir);
|
|
339
|
+
const urlMatch = deployOutput.match(/https:\/\/[^\s]+\.workers\.dev/);
|
|
340
|
+
if (urlMatch) cf.url = urlMatch[0];
|
|
341
|
+
cf.deployed = true;
|
|
342
|
+
s.stop("Deployed to Cloudflare");
|
|
343
|
+
} catch (err) {
|
|
344
|
+
s.stop("Deploy failed — run manually with: pnpm run deploy");
|
|
345
|
+
if (err.stderr) console.error(err.stderr.slice(-500));
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
309
349
|
}
|
|
310
350
|
}
|
|
311
351
|
}
|
|
@@ -321,26 +361,34 @@ async function main() {
|
|
|
321
361
|
console.log(` To start again: cd ${projectName} && pnpm dev\n`);
|
|
322
362
|
}
|
|
323
363
|
} else {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
)
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
364
|
+
if (cf.deployed && cf.url) {
|
|
365
|
+
p.note([`Live at: ${cf.url}`, `Admin: ${cf.url}/admin`, "", `cd ${projectName}`, "", "Local development:", ` ${pm.run} dev`, "", "Redeploy:", " pnpm run deploy"].join("\n"), "🎉 Your Kide CMS is live");
|
|
366
|
+
p.outro("Project created!");
|
|
367
|
+
} else {
|
|
368
|
+
const lines = [`cd ${projectName}`];
|
|
369
|
+
const remaining = [];
|
|
370
|
+
if (!cf.d1Created) {
|
|
371
|
+
remaining.push(
|
|
372
|
+
` ${pm.exec} wrangler d1 create ${projectName}-db`,
|
|
373
|
+
" # Copy the database_id to wrangler.toml",
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
if (!cf.r2Created) {
|
|
377
|
+
remaining.push(` ${pm.exec} wrangler r2 bucket create ${projectName}-assets`);
|
|
378
|
+
}
|
|
379
|
+
if (!cf.migrationsApplied) {
|
|
380
|
+
remaining.push(` ${pm.exec} wrangler d1 migrations apply ${projectName}-db --remote`);
|
|
381
|
+
}
|
|
382
|
+
if (!cf.deployed) {
|
|
383
|
+
remaining.push(` ${pm.run} run deploy`);
|
|
384
|
+
}
|
|
385
|
+
if (remaining.length > 0) {
|
|
386
|
+
lines.push("", "Remaining setup:", ...remaining);
|
|
387
|
+
}
|
|
388
|
+
lines.push("", "Local development:", ` ${pm.run} dev`);
|
|
389
|
+
p.note(lines.join("\n"), "Next steps");
|
|
390
|
+
p.outro("Project created!");
|
|
340
391
|
}
|
|
341
|
-
lines.push("", "Local development:", ` ${pm.run} dev`, "", "Deploy:", " pnpm run deploy");
|
|
342
|
-
p.note(lines.join("\n"), "Next steps");
|
|
343
|
-
p.outro("Project created!");
|
|
344
392
|
}
|
|
345
393
|
}
|
|
346
394
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { readdirSync } from "node:fs";
|
|
1
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
2
2
|
import { defineConfig } from "drizzle-kit";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Look for the local D1 sqlite file (created by wrangler after first run).
|
|
5
|
+
// Returns null if it doesn't exist yet — `drizzle-kit generate` doesn't need it.
|
|
6
|
+
function getLocalD1Path(): string | null {
|
|
5
7
|
const dir = ".wrangler/state/v3/d1/miniflare-D1DatabaseObject";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
if (!existsSync(dir)) return null;
|
|
9
|
+
try {
|
|
10
|
+
const file = readdirSync(dir).find((f) => f.endsWith(".sqlite") && f !== "*.sqlite");
|
|
11
|
+
return file ? `${dir}/${file}` : null;
|
|
12
|
+
} catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
export default defineConfig({
|
|
@@ -13,6 +19,6 @@ export default defineConfig({
|
|
|
13
19
|
out: "./src/cms/migrations",
|
|
14
20
|
dialect: "sqlite",
|
|
15
21
|
dbCredentials: {
|
|
16
|
-
url: getLocalD1Path(),
|
|
22
|
+
url: getLocalD1Path() ?? ":memory:",
|
|
17
23
|
},
|
|
18
24
|
});
|