create-kide-app 0.3.4 → 0.3.6

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.
Files changed (2) hide show
  1. package/index.js +49 -24
  2. package/package.json +1 -1
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 { execFileSync, execSync, spawn } from "node:child_process";
4
+ import { execSync, spawn } from "node:child_process";
5
5
  import {
6
6
  cpSync,
7
7
  existsSync,
@@ -31,6 +31,27 @@ const runAsync = (cmd, cwd) =>
31
31
  });
32
32
  });
33
33
 
34
+ // Argv-based variant: no shell, so untrusted values (like the project directory)
35
+ // are passed as single arguments and can never be reinterpreted as commands.
36
+ const runFileAsync = (file, args, cwd) =>
37
+ new Promise((resolve, reject) => {
38
+ const child = spawn(file, args, { cwd });
39
+ let stdout = "";
40
+ let stderr = "";
41
+ child.stdout.on("data", (d) => (stdout += d.toString()));
42
+ child.stderr.on("data", (d) => (stderr += d.toString()));
43
+ child.on("error", reject);
44
+ child.on("close", (code) => {
45
+ if (code === 0) resolve(stdout);
46
+ else {
47
+ const err = new Error(`Command failed: ${file} ${args.join(" ")}`);
48
+ err.stderr = stderr;
49
+ err.stdout = stdout;
50
+ reject(err);
51
+ }
52
+ });
53
+ });
54
+
34
55
  // --- Package manager detection ---
35
56
 
36
57
  const pm = {
@@ -97,13 +118,17 @@ const validateProjectName = (value) => {
97
118
 
98
119
  // Resolve the latest release tag (v-prefixed semver) so scaffolds pin to a
99
120
  // deliberate release instead of whatever HEAD happens to be. Returns null when
100
- // the repo has no tags (falls back to the default branch).
101
- const resolveLatestTag = () => {
121
+ // the repo has no tags (falls back to the default branch). Async so the
122
+ // "Downloading template" spinner keeps animating during the network call.
123
+ const resolveLatestTag = async () => {
102
124
  try {
103
- const output = execSync(
104
- `git ls-remote --tags --sort=-v:refname ${REPO} "v*"`,
105
- { stdio: "pipe" },
106
- ).toString();
125
+ const output = await runFileAsync("git", [
126
+ "ls-remote",
127
+ "--tags",
128
+ "--sort=-v:refname",
129
+ REPO,
130
+ "v*",
131
+ ]);
107
132
  for (const line of output.split("\n")) {
108
133
  const match = line.match(/refs\/tags\/(v[0-9][^^\s]*)$/);
109
134
  if (match) return match[1];
@@ -195,27 +220,14 @@ async function main() {
195
220
 
196
221
  s.start("Downloading template");
197
222
 
198
- const templateRef = resolveLatestTag();
223
+ const templateRef = await resolveLatestTag();
199
224
  let templateCommit = null;
200
225
 
201
226
  try {
202
227
  const branchArgs = templateRef ? ["--branch", templateRef] : [];
203
- // execFileSync, not execSync: no shell, so projectDir is passed as one argv entry
204
- // and can never be reinterpreted as a command regardless of what it contains.
205
- execFileSync(
206
- "git",
207
- ["clone", "--depth", "1", ...branchArgs, REPO, projectDir],
208
- {
209
- stdio: "pipe",
210
- },
211
- );
228
+ await runFileAsync("git", ["clone", "--depth", "1", ...branchArgs, REPO, projectDir]);
212
229
  try {
213
- templateCommit = execSync("git rev-parse HEAD", {
214
- cwd: projectDir,
215
- stdio: "pipe",
216
- })
217
- .toString()
218
- .trim();
230
+ templateCommit = (await runFileAsync("git", ["rev-parse", "HEAD"], projectDir)).trim();
219
231
  } catch {
220
232
  // best-effort — stamp without a commit hash
221
233
  }
@@ -723,12 +735,25 @@ async function main() {
723
735
  s.stop("Schema generation failed — run `cms:generate` manually");
724
736
  }
725
737
 
738
+ // --- Apply schema to the local database (local target only; Cloudflare's D1
739
+ // needs Worker bindings). Without this, only `pnpm dev` (which pushes on boot)
740
+ // works out of the box — `pnpm build && pnpm preview` would hit a table-less DB.
741
+
742
+ if (target === "local") {
743
+ s.start("Preparing database");
744
+ try {
745
+ await runAsync(`${pm.run} cms:push`, projectDir);
746
+ s.stop("Database ready");
747
+ } catch {
748
+ s.stop("Database push failed — run `pnpm cms:push` manually");
749
+ }
750
+ }
751
+
726
752
  // --- Seed starter content (local target only) ---
727
753
 
728
754
  if (starter && seedRequested && target === "local") {
729
755
  s.start("Seeding example content");
730
756
  try {
731
- await runAsync(`${pm.run} cms:push`, projectDir);
732
757
  await runAsync(`${pm.exec} kide seed`, projectDir);
733
758
  s.stop("Example content seeded");
734
759
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-kide-app",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Scaffold a new Kide CMS project",
5
5
  "author": "Matti Hernesniemi",
6
6
  "license": "MIT",