create-kide-app 0.2.3 → 0.3.1
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/README.md +22 -3
- package/index.js +271 -84
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -11,10 +11,29 @@ pnpm create kide-app my-project
|
|
|
11
11
|
The CLI asks for:
|
|
12
12
|
|
|
13
13
|
1. **Project name** — directory to create
|
|
14
|
-
2. **
|
|
15
|
-
3. **
|
|
14
|
+
2. **Starter template** — Blank (default: one `pages` collection, no demo content) or a starter shipped with the template release, e.g. Marketing site (pages with blocks, blog, menu, contact form). Starters can seed example content into the local database.
|
|
15
|
+
3. **Distribution mode** — Package (recommended: thin project + `@kidecms/core` npm dependency; `pnpm exec kide eject` converts to embedded later, one-way) or Embedded (full CMS source in `src/cms/`, yours to modify)
|
|
16
|
+
4. **Deploy target** — Local/Node.js or Cloudflare
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
## Non-interactive use
|
|
19
|
+
|
|
20
|
+
Every prompt can be answered with a flag; supplied answers skip their prompts.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm create kide-app my-app --starter=marketing --seed --mode=embedded --target=local --no-github --no-dev
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
| Flag | Values |
|
|
27
|
+
| ---- | ------ |
|
|
28
|
+
| `--starter=` | `blank` or a starter name from the template release |
|
|
29
|
+
| `--seed` / `--no-seed` | Seed example content (local target only) |
|
|
30
|
+
| `--mode=` | `package` or `embedded` |
|
|
31
|
+
| `--target=` | `local` or `cloudflare` |
|
|
32
|
+
| `--no-github` | Skip the GitHub repo prompt |
|
|
33
|
+
| `--no-dev` | Skip the dev-server prompt |
|
|
34
|
+
| `--no-cloudflare-setup` | Skip Cloudflare resource provisioning |
|
|
35
|
+
|
|
36
|
+
The template repo can be overridden with the `KIDE_TEMPLATE_REPO` env var (forks, local testing).
|
|
18
37
|
|
|
19
38
|
## What it does
|
|
20
39
|
|
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { execFileSync, execSync, spawn } from "node:child_process";
|
|
|
5
5
|
import {
|
|
6
6
|
cpSync,
|
|
7
7
|
existsSync,
|
|
8
|
+
readdirSync,
|
|
8
9
|
readFileSync,
|
|
9
10
|
rmSync,
|
|
10
11
|
writeFileSync,
|
|
@@ -42,7 +43,11 @@ const pm = {
|
|
|
42
43
|
|
|
43
44
|
// --- Template repo ---
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
// Overridable for forks and for testing against a local checkout
|
|
47
|
+
// (e.g. KIDE_TEMPLATE_REPO=file:///path/to/kide-cms).
|
|
48
|
+
const REPO =
|
|
49
|
+
process.env.KIDE_TEMPLATE_REPO ||
|
|
50
|
+
"https://github.com/mhernesniemi/kide-cms.git";
|
|
46
51
|
|
|
47
52
|
// Files from the kide-cms repo that shouldn't leak into scaffolded projects.
|
|
48
53
|
// NOTE: `.claude/settings.local.json` is removed but `.claude/skills/` is kept,
|
|
@@ -106,14 +111,50 @@ const resolveLatestTag = () => {
|
|
|
106
111
|
return null;
|
|
107
112
|
};
|
|
108
113
|
|
|
114
|
+
// --- CLI flags (non-interactive use: CI, agents, testing) ---
|
|
115
|
+
// Any prompt whose answer is supplied by a flag is skipped. Example:
|
|
116
|
+
// create-kide-app my-app --starter=marketing --seed --mode=embedded --target=local --no-github --no-dev
|
|
117
|
+
|
|
118
|
+
const parseArgs = (argv) => {
|
|
119
|
+
const flags = {};
|
|
120
|
+
const positional = [];
|
|
121
|
+
for (const arg of argv) {
|
|
122
|
+
if (arg === "--seed") flags.seed = true;
|
|
123
|
+
else if (arg === "--no-seed") flags.seed = false;
|
|
124
|
+
else if (arg === "--no-github") flags.noGithub = true;
|
|
125
|
+
else if (arg === "--no-dev") flags.noDev = true;
|
|
126
|
+
else if (arg === "--no-cloudflare-setup") flags.noCloudflareSetup = true;
|
|
127
|
+
else if (arg.startsWith("--starter=")) flags.starter = arg.slice("--starter=".length);
|
|
128
|
+
else if (arg.startsWith("--mode=")) flags.mode = arg.slice("--mode=".length);
|
|
129
|
+
else if (arg.startsWith("--target=")) flags.target = arg.slice("--target=".length);
|
|
130
|
+
else if (arg.startsWith("--")) flags.unknown = arg;
|
|
131
|
+
else positional.push(arg);
|
|
132
|
+
}
|
|
133
|
+
return { flags, positional };
|
|
134
|
+
};
|
|
135
|
+
|
|
109
136
|
// --- Main ---
|
|
110
137
|
|
|
111
138
|
async function main() {
|
|
112
139
|
p.intro("🪐 Create Kide CMS Project");
|
|
113
140
|
|
|
141
|
+
const { flags, positional } = parseArgs(process.argv.slice(2));
|
|
142
|
+
if (flags.unknown) {
|
|
143
|
+
p.cancel(`Unknown flag: ${flags.unknown}`);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
if (flags.mode !== undefined && !["package", "embedded"].includes(flags.mode)) {
|
|
147
|
+
p.cancel(`--mode must be "package" or "embedded".`);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
if (flags.target !== undefined && !["local", "cloudflare"].includes(flags.target)) {
|
|
151
|
+
p.cancel(`--target must be "local" or "cloudflare".`);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
|
|
114
155
|
// 1. Project name
|
|
115
156
|
const projectName =
|
|
116
|
-
|
|
157
|
+
positional[0] ||
|
|
117
158
|
(await p.text({
|
|
118
159
|
message: "Project name",
|
|
119
160
|
placeholder: "my-cms-app",
|
|
@@ -142,48 +183,14 @@ async function main() {
|
|
|
142
183
|
process.exit(1);
|
|
143
184
|
}
|
|
144
185
|
|
|
145
|
-
// 2. Distribution mode — package is the recommended default; embedded stays
|
|
146
|
-
// first-class for teams that want to own and modify the runtime source.
|
|
147
|
-
const mode = await p.select({
|
|
148
|
-
message: "How do you want the CMS runtime?",
|
|
149
|
-
options: [
|
|
150
|
-
{
|
|
151
|
-
label: "Package",
|
|
152
|
-
value: "package",
|
|
153
|
-
hint: "@kidecms/core dependency",
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
label: "Embedded",
|
|
157
|
-
value: "embedded",
|
|
158
|
-
hint: "full CMS source in src/cms/, yours to modify",
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
if (p.isCancel(mode)) {
|
|
164
|
-
p.cancel("Setup cancelled.");
|
|
165
|
-
process.exit(0);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// 3. Deploy target
|
|
169
|
-
const target = await p.select({
|
|
170
|
-
message: "Where will you deploy?",
|
|
171
|
-
options: [
|
|
172
|
-
{ label: "Local / Node.js", value: "local" },
|
|
173
|
-
{ label: "Cloudflare", value: "cloudflare" },
|
|
174
|
-
],
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
if (p.isCancel(target)) {
|
|
178
|
-
p.cancel("Setup cancelled.");
|
|
179
|
-
process.exit(0);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
186
|
const s = p.spinner();
|
|
183
187
|
|
|
184
188
|
// --- Scaffold via git clone ---
|
|
189
|
+
// The clone happens before the remaining prompts so the starter list can be
|
|
190
|
+
// read from the cloned tag — new starters ship with template releases, no CLI
|
|
191
|
+
// release needed.
|
|
185
192
|
|
|
186
|
-
s.start(
|
|
193
|
+
s.start("Downloading template");
|
|
187
194
|
|
|
188
195
|
const templateRef = resolveLatestTag();
|
|
189
196
|
let templateCommit = null;
|
|
@@ -211,6 +218,7 @@ async function main() {
|
|
|
211
218
|
}
|
|
212
219
|
rmSync(path.join(projectDir, ".git"), { recursive: true, force: true });
|
|
213
220
|
} catch {
|
|
221
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
214
222
|
s.stop("Failed to download template.");
|
|
215
223
|
p.cancel("Check your network connection.");
|
|
216
224
|
process.exit(1);
|
|
@@ -221,6 +229,148 @@ async function main() {
|
|
|
221
229
|
rmSync(path.join(projectDir, f), { recursive: true, force: true });
|
|
222
230
|
}
|
|
223
231
|
|
|
232
|
+
s.stop(templateRef ? `Template ready (${templateRef})` : "Template ready");
|
|
233
|
+
|
|
234
|
+
// From here on the clone exists, so a cancelled prompt must remove it.
|
|
235
|
+
const cancelSetup = (message = "Setup cancelled.") => {
|
|
236
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
237
|
+
p.cancel(message);
|
|
238
|
+
process.exit(0);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// 2. Starter template — options come from starters/*/starter.json in the
|
|
242
|
+
// cloned tag. Older tags have no starters/ dir; the prompt is skipped and the
|
|
243
|
+
// scaffold stays blank.
|
|
244
|
+
const startersDir = path.join(projectDir, "starters");
|
|
245
|
+
const starterOptions = [];
|
|
246
|
+
if (existsSync(startersDir)) {
|
|
247
|
+
for (const entry of readdirSync(startersDir, { withFileTypes: true })) {
|
|
248
|
+
if (!entry.isDirectory()) continue;
|
|
249
|
+
const manifestPath = path.join(startersDir, entry.name, "starter.json");
|
|
250
|
+
if (!existsSync(manifestPath)) continue;
|
|
251
|
+
try {
|
|
252
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
253
|
+
starterOptions.push({
|
|
254
|
+
label: manifest.label ?? entry.name,
|
|
255
|
+
value: entry.name,
|
|
256
|
+
hint: manifest.hint,
|
|
257
|
+
order: manifest.order ?? 100,
|
|
258
|
+
});
|
|
259
|
+
} catch {
|
|
260
|
+
// unreadable manifest — skip this starter
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
starterOptions.sort((a, b) => a.order - b.order);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
let starter = null;
|
|
267
|
+
if (flags.starter !== undefined) {
|
|
268
|
+
if (flags.starter !== "blank") {
|
|
269
|
+
if (!starterOptions.some((option) => option.value === flags.starter)) {
|
|
270
|
+
cancelSetup(
|
|
271
|
+
`Unknown starter "${flags.starter}". Available: blank${starterOptions.map((o) => `, ${o.value}`).join("")}`,
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
starter = flags.starter;
|
|
275
|
+
}
|
|
276
|
+
} else if (starterOptions.length > 0) {
|
|
277
|
+
const choice = await p.select({
|
|
278
|
+
message: "Starter template",
|
|
279
|
+
options: [
|
|
280
|
+
{ label: "Blank", value: null, hint: "empty schema, no demo content" },
|
|
281
|
+
...starterOptions.map(({ label, value, hint }) => ({
|
|
282
|
+
label,
|
|
283
|
+
value,
|
|
284
|
+
hint,
|
|
285
|
+
})),
|
|
286
|
+
],
|
|
287
|
+
});
|
|
288
|
+
if (p.isCancel(choice)) cancelSetup();
|
|
289
|
+
starter = choice;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// 3. Distribution mode — package is the recommended default; embedded stays
|
|
293
|
+
// first-class for teams that want to own and modify the runtime source.
|
|
294
|
+
const mode =
|
|
295
|
+
flags.mode ??
|
|
296
|
+
(await p.select({
|
|
297
|
+
message: "How do you want the CMS runtime?",
|
|
298
|
+
options: [
|
|
299
|
+
{
|
|
300
|
+
label: "Package",
|
|
301
|
+
value: "package",
|
|
302
|
+
hint: "@kidecms/core dependency",
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
label: "Embedded",
|
|
306
|
+
value: "embedded",
|
|
307
|
+
hint: "full CMS source in src/cms/, yours to modify",
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
}));
|
|
311
|
+
|
|
312
|
+
if (p.isCancel(mode)) cancelSetup();
|
|
313
|
+
|
|
314
|
+
// 4. Deploy target
|
|
315
|
+
const target =
|
|
316
|
+
flags.target ??
|
|
317
|
+
(await p.select({
|
|
318
|
+
message: "Where will you deploy?",
|
|
319
|
+
options: [
|
|
320
|
+
{ label: "Local / Node.js", value: "local" },
|
|
321
|
+
{ label: "Cloudflare", value: "cloudflare" },
|
|
322
|
+
],
|
|
323
|
+
}));
|
|
324
|
+
|
|
325
|
+
if (p.isCancel(target)) cancelSetup();
|
|
326
|
+
|
|
327
|
+
// Seeding runs at scaffold time and needs the local db adapter — the
|
|
328
|
+
// Cloudflare adapter needs Worker bindings, so the question is local-only.
|
|
329
|
+
let seedRequested = false;
|
|
330
|
+
if (starter && target === "local") {
|
|
331
|
+
if (flags.seed !== undefined) {
|
|
332
|
+
seedRequested = flags.seed;
|
|
333
|
+
} else {
|
|
334
|
+
const seedChoice = await p.confirm({
|
|
335
|
+
message: "Seed example content?",
|
|
336
|
+
initialValue: true,
|
|
337
|
+
});
|
|
338
|
+
if (p.isCancel(seedChoice)) cancelSetup();
|
|
339
|
+
seedRequested = seedChoice;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// The npm artifact publishes after the template tag (CI runs the release gate
|
|
344
|
+
// first) — a package-mode scaffold in that window would fail install with a
|
|
345
|
+
// missing version. Fail early with a clear message instead.
|
|
346
|
+
if (mode === "package") {
|
|
347
|
+
const clonedCorePkg = path.join(projectDir, "src/cms/package.json");
|
|
348
|
+
const clonedCoreVersion = existsSync(clonedCorePkg)
|
|
349
|
+
? JSON.parse(readFileSync(clonedCorePkg, "utf-8")).version
|
|
350
|
+
: null;
|
|
351
|
+
if (clonedCoreVersion) {
|
|
352
|
+
try {
|
|
353
|
+
execSync(`npm view @kidecms/core@${clonedCoreVersion} version`, {
|
|
354
|
+
stdio: "pipe",
|
|
355
|
+
});
|
|
356
|
+
} catch {
|
|
357
|
+
cancelSetup(
|
|
358
|
+
`@kidecms/core@${clonedCoreVersion} is not on npm yet — if this release was just tagged, publishing may still be running. Retry in a few minutes, or choose Embedded mode.`,
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
s.start(`Configuring project (using ${pm.name})`);
|
|
365
|
+
|
|
366
|
+
// Apply the starter overlay — project-owned files copied over the barebone
|
|
367
|
+
// base. starter.json is manifest metadata, not project content.
|
|
368
|
+
if (starter) {
|
|
369
|
+
cpSync(path.join(startersDir, starter), projectDir, { recursive: true });
|
|
370
|
+
rmSync(path.join(projectDir, "starter.json"), { force: true });
|
|
371
|
+
}
|
|
372
|
+
rmSync(startersDir, { recursive: true, force: true });
|
|
373
|
+
|
|
224
374
|
// Both modes scaffold the same template at the same tag; package mode then
|
|
225
375
|
// deletes the managed runtime dirs and swaps the workspace link for the
|
|
226
376
|
// published @kidecms/core at exactly that version — same source either way.
|
|
@@ -404,6 +554,7 @@ async function main() {
|
|
|
404
554
|
commit: templateCommit,
|
|
405
555
|
target,
|
|
406
556
|
mode,
|
|
557
|
+
starter: starter ?? null,
|
|
407
558
|
corePath: "src/cms",
|
|
408
559
|
scaffoldedAt: new Date().toISOString(),
|
|
409
560
|
createKideApp: cliVersion,
|
|
@@ -471,7 +622,7 @@ async function main() {
|
|
|
471
622
|
// gh not installed or not authenticated — skip the prompt
|
|
472
623
|
}
|
|
473
624
|
|
|
474
|
-
if (ghAvailable) {
|
|
625
|
+
if (ghAvailable && !flags.noGithub) {
|
|
475
626
|
const createRepo = await p.confirm({
|
|
476
627
|
message: "Create a GitHub repository for this project?",
|
|
477
628
|
initialValue: false,
|
|
@@ -567,6 +718,21 @@ async function main() {
|
|
|
567
718
|
s.stop("Schema generation failed — run `cms:generate` manually");
|
|
568
719
|
}
|
|
569
720
|
|
|
721
|
+
// --- Seed starter content (local target only) ---
|
|
722
|
+
|
|
723
|
+
if (starter && seedRequested && target === "local") {
|
|
724
|
+
s.start("Seeding example content");
|
|
725
|
+
try {
|
|
726
|
+
await runAsync(`${pm.run} cms:push`, projectDir);
|
|
727
|
+
await runAsync(`${pm.exec} kide seed`, projectDir);
|
|
728
|
+
s.stop("Example content seeded");
|
|
729
|
+
} catch {
|
|
730
|
+
s.stop(
|
|
731
|
+
"Seeding failed — run `pnpm cms:push && pnpm cms:seed` manually",
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
570
736
|
// --- Cloudflare resource setup ---
|
|
571
737
|
|
|
572
738
|
const cf = {
|
|
@@ -577,39 +743,60 @@ async function main() {
|
|
|
577
743
|
url: null,
|
|
578
744
|
};
|
|
579
745
|
if (target === "cloudflare") {
|
|
580
|
-
const setupNow =
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
746
|
+
const setupNow =
|
|
747
|
+
flags.noCloudflareSetup === true
|
|
748
|
+
? false
|
|
749
|
+
: await p.confirm({
|
|
750
|
+
message:
|
|
751
|
+
"Set up Cloudflare resources now? (creates D1 database and R2 bucket)",
|
|
752
|
+
initialValue: true,
|
|
753
|
+
});
|
|
585
754
|
|
|
586
755
|
if (!p.isCancel(setupNow) && setupNow) {
|
|
587
|
-
//
|
|
588
|
-
|
|
756
|
+
// A missing wrangler binary (e.g. dependency install failed) must not be
|
|
757
|
+
// misread as "not logged in" — check presence before authentication.
|
|
758
|
+
let wranglerAvailable = false;
|
|
589
759
|
try {
|
|
590
|
-
execSync(`${pm.exec} wrangler
|
|
760
|
+
execSync(`${pm.exec} wrangler --version`, {
|
|
591
761
|
cwd: projectDir,
|
|
592
762
|
stdio: "pipe",
|
|
593
763
|
});
|
|
594
|
-
|
|
764
|
+
wranglerAvailable = true;
|
|
595
765
|
} catch {
|
|
596
766
|
p.note(
|
|
597
|
-
"
|
|
598
|
-
"Wrangler
|
|
767
|
+
"wrangler is not installed — dependency install may have failed.\nRun `pnpm install`, then finish the setup steps listed below.",
|
|
768
|
+
"Wrangler missing",
|
|
599
769
|
);
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// Check wrangler authentication
|
|
773
|
+
let authenticated = false;
|
|
774
|
+
if (wranglerAvailable) {
|
|
775
|
+
try {
|
|
776
|
+
execSync(`${pm.exec} wrangler whoami`, {
|
|
777
|
+
cwd: projectDir,
|
|
778
|
+
stdio: "pipe",
|
|
779
|
+
});
|
|
780
|
+
authenticated = true;
|
|
781
|
+
} catch {
|
|
782
|
+
p.note(
|
|
783
|
+
"You need to log in to Cloudflare first.",
|
|
784
|
+
"Wrangler login required",
|
|
785
|
+
);
|
|
786
|
+
const doLogin = await p.confirm({
|
|
787
|
+
message: "Open browser to log in?",
|
|
788
|
+
initialValue: true,
|
|
789
|
+
});
|
|
790
|
+
if (!p.isCancel(doLogin) && doLogin) {
|
|
791
|
+
try {
|
|
792
|
+
execSync(`${pm.exec} wrangler login`, {
|
|
793
|
+
cwd: projectDir,
|
|
794
|
+
stdio: "inherit",
|
|
795
|
+
});
|
|
796
|
+
authenticated = true;
|
|
797
|
+
} catch {
|
|
798
|
+
s.stop("Login failed");
|
|
799
|
+
}
|
|
613
800
|
}
|
|
614
801
|
}
|
|
615
802
|
}
|
|
@@ -757,10 +944,12 @@ async function main() {
|
|
|
757
944
|
// --- Done ---
|
|
758
945
|
|
|
759
946
|
if (target === "local") {
|
|
760
|
-
const startDev =
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
947
|
+
const startDev = flags.noDev
|
|
948
|
+
? false
|
|
949
|
+
: await p.confirm({
|
|
950
|
+
message: "Start the dev server now?",
|
|
951
|
+
initialValue: true,
|
|
952
|
+
});
|
|
764
953
|
|
|
765
954
|
if (!p.isCancel(startDev) && startDev) {
|
|
766
955
|
p.outro("Starting dev server...");
|
|
@@ -779,21 +968,19 @@ async function main() {
|
|
|
779
968
|
}
|
|
780
969
|
} else {
|
|
781
970
|
if (cf.deployed && cf.url) {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
"🎉 Your Kide CMS is live",
|
|
796
|
-
);
|
|
971
|
+
const liveLines = [
|
|
972
|
+
`Live at: ${cf.url}`,
|
|
973
|
+
`Admin: ${cf.url}/admin`,
|
|
974
|
+
"",
|
|
975
|
+
`cd ${projectName}`,
|
|
976
|
+
"",
|
|
977
|
+
"Local development:",
|
|
978
|
+
` ${pm.run} dev`,
|
|
979
|
+
"",
|
|
980
|
+
"Redeploy:",
|
|
981
|
+
" pnpm run deploy",
|
|
982
|
+
];
|
|
983
|
+
p.note(liveLines.join("\n"), "🎉 Your Kide CMS is live");
|
|
797
984
|
p.outro("Project created!");
|
|
798
985
|
} else {
|
|
799
986
|
const lines = [`cd ${projectName}`];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-kide-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Scaffold a new Kide CMS project",
|
|
5
5
|
"author": "Matti Hernesniemi",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"create-kide-app": "./index.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"release": "npm version patch && git push --follow-tags && npm publish"
|
|
12
|
+
"release": "npm version patch && git push --follow-tags && npm publish",
|
|
13
|
+
"release:minor": "npm version minor && git push --follow-tags && npm publish"
|
|
13
14
|
},
|
|
14
15
|
"files": [
|
|
15
16
|
"index.js"
|