@korajs/cli 1.0.0-beta.12 → 1.0.0-beta.14
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 +25 -107
- package/dist/bin.cjs +808 -340
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +588 -174
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-G2PBYMMA.js → chunk-7Y4J2GXP.js} +168 -153
- package/dist/chunk-7Y4J2GXP.js.map +1 -0
- package/dist/{chunk-Z7GCXMGW.js → chunk-BURFQVMV.js} +44 -9
- package/dist/chunk-BURFQVMV.js.map +1 -0
- package/dist/{chunk-4IKCHRJ6.js → chunk-TVIRMDER.js} +122 -112
- package/dist/chunk-TVIRMDER.js.map +1 -0
- package/dist/create.cjs +63 -28
- package/dist/create.cjs.map +1 -1
- package/dist/create.js +2 -2
- package/dist/index.cjs +41 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +8 -2
- package/dist/{studio-server-NIFKZI4F.js → studio-server-XLGZNGG5.js} +11 -2
- package/dist/studio-server-XLGZNGG5.js.map +1 -0
- package/dist/vite.cjs +351 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.cts +161 -0
- package/dist/vite.d.ts +161 -0
- package/dist/vite.js +321 -0
- package/dist/vite.js.map +1 -0
- package/package.json +18 -8
- package/templates/react-basic/AGENTS.md +5 -5
- package/templates/react-basic/vite.config.ts +4 -1
- package/templates/react-sync/.env.example +1 -1
- package/templates/react-sync/AGENTS.md +5 -5
- package/templates/react-sync/server.ts +8 -0
- package/templates/react-sync/src/vite-env.d.ts +1 -0
- package/templates/react-sync/vite.config.ts +4 -1
- package/templates/react-tailwind/AGENTS.md +5 -5
- package/templates/react-tailwind/vite.config.ts +10 -1
- package/templates/react-tailwind-sync/.env.example +1 -1
- package/templates/react-tailwind-sync/AGENTS.md +9 -7
- package/templates/react-tailwind-sync/server.ts +8 -0
- package/templates/react-tailwind-sync/src/App.tsx +1 -1
- package/templates/react-tailwind-sync/src/kora.ts +32 -0
- package/templates/react-tailwind-sync/src/main.tsx +1 -23
- package/templates/react-tailwind-sync/src/modules/todos/todo.mutations.ts +4 -8
- package/templates/react-tailwind-sync/src/modules/todos/todo.queries.ts +2 -2
- package/templates/react-tailwind-sync/src/modules/todos/useTodos.ts +1 -1
- package/templates/react-tailwind-sync/src/vite-env.d.ts +1 -0
- package/templates/react-tailwind-sync/vite.config.ts +10 -1
- package/templates/svelte-basic/AGENTS.md +4 -4
- package/templates/svelte-basic/package.json.hbs +6 -0
- package/templates/svelte-basic/src/App.svelte +2 -1
- package/templates/svelte-basic/vite.config.ts +4 -1
- package/templates/svelte-sync/.env.example +1 -1
- package/templates/svelte-sync/AGENTS.md +4 -4
- package/templates/svelte-sync/server.ts +8 -0
- package/templates/svelte-sync/src/App.svelte +2 -1
- package/templates/svelte-sync/vite.config.ts +4 -1
- package/templates/svelte-tailwind/AGENTS.md +4 -4
- package/templates/svelte-tailwind/package.json.hbs +7 -1
- package/templates/svelte-tailwind/src/App.svelte +2 -1
- package/templates/svelte-tailwind/vite.config.ts +10 -1
- package/templates/svelte-tailwind-sync/.env.example +1 -1
- package/templates/svelte-tailwind-sync/AGENTS.md +4 -4
- package/templates/svelte-tailwind-sync/package.json.hbs +1 -1
- package/templates/svelte-tailwind-sync/server.ts +8 -0
- package/templates/svelte-tailwind-sync/src/App.svelte +2 -1
- package/templates/svelte-tailwind-sync/vite.config.ts +10 -1
- package/templates/tauri-react/.env.example +1 -1
- package/templates/tauri-react/AGENTS.md +5 -5
- package/templates/tauri-react/README.md.hbs +2 -2
- package/templates/tauri-react/package.json.hbs +1 -1
- package/templates/tauri-react/server.ts +10 -2
- package/templates/tauri-react/src/vite-env.d.ts +1 -0
- package/templates/vue-basic/AGENTS.md +4 -4
- package/templates/vue-basic/package.json.hbs +6 -0
- package/templates/vue-basic/vite.config.ts +4 -1
- package/templates/vue-sync/.env.example +1 -1
- package/templates/vue-sync/AGENTS.md +4 -4
- package/templates/vue-sync/server.ts +8 -0
- package/templates/vue-sync/vite.config.ts +4 -1
- package/templates/vue-tailwind/AGENTS.md +4 -4
- package/templates/vue-tailwind/package.json.hbs +6 -0
- package/templates/vue-tailwind/vite.config.ts +4 -1
- package/templates/vue-tailwind-sync/.env.example +1 -1
- package/templates/vue-tailwind-sync/AGENTS.md +4 -4
- package/templates/vue-tailwind-sync/server.ts +8 -0
- package/templates/vue-tailwind-sync/vite.config.ts +4 -1
- package/dist/chunk-4IKCHRJ6.js.map +0 -1
- package/dist/chunk-G2PBYMMA.js.map +0 -1
- package/dist/chunk-Z7GCXMGW.js.map +0 -1
- package/dist/studio-server-NIFKZI4F.js.map +0 -1
|
@@ -1,5 +1,90 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/types.ts
|
|
4
|
+
var PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"];
|
|
5
|
+
var TEMPLATES = [
|
|
6
|
+
"react-tailwind-sync",
|
|
7
|
+
"react-tailwind",
|
|
8
|
+
"react-sync",
|
|
9
|
+
"react-basic",
|
|
10
|
+
"vue-sync",
|
|
11
|
+
"vue-basic",
|
|
12
|
+
"vue-tailwind-sync",
|
|
13
|
+
"vue-tailwind",
|
|
14
|
+
"svelte-sync",
|
|
15
|
+
"svelte-basic",
|
|
16
|
+
"svelte-tailwind-sync",
|
|
17
|
+
"svelte-tailwind",
|
|
18
|
+
"tauri-react"
|
|
19
|
+
];
|
|
20
|
+
var TEMPLATE_INFO = [
|
|
21
|
+
{
|
|
22
|
+
name: "react-tailwind-sync",
|
|
23
|
+
label: "React + Tailwind (with sync)",
|
|
24
|
+
description: "Polished dark-themed app with Tailwind CSS and sync server (Recommended)"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "react-tailwind",
|
|
28
|
+
label: "React + Tailwind (local-only)",
|
|
29
|
+
description: "Polished dark-themed app with Tailwind CSS \u2014 no sync server"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "react-sync",
|
|
33
|
+
label: "React + CSS (with sync)",
|
|
34
|
+
description: "Clean CSS app with sync server included"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "react-basic",
|
|
38
|
+
label: "React + CSS (local-only)",
|
|
39
|
+
description: "Clean CSS app \u2014 no sync server"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "vue-sync",
|
|
43
|
+
label: "Vue 3 + CSS (with sync)",
|
|
44
|
+
description: "Vue composables with sync server included"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "vue-basic",
|
|
48
|
+
label: "Vue 3 + CSS (local-only)",
|
|
49
|
+
description: "Vue composables \u2014 no sync server"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "vue-tailwind-sync",
|
|
53
|
+
label: "Vue 3 + Tailwind (with sync)",
|
|
54
|
+
description: "Polished Vue app with Tailwind CSS and sync server"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "vue-tailwind",
|
|
58
|
+
label: "Vue 3 + Tailwind (local-only)",
|
|
59
|
+
description: "Polished Vue app with Tailwind CSS \u2014 no sync server"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "svelte-sync",
|
|
63
|
+
label: "Svelte 5 + CSS (with sync)",
|
|
64
|
+
description: "Svelte stores with sync server included"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "svelte-basic",
|
|
68
|
+
label: "Svelte 5 + CSS (local-only)",
|
|
69
|
+
description: "Svelte stores \u2014 no sync server"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "svelte-tailwind-sync",
|
|
73
|
+
label: "Svelte 5 + Tailwind (with sync)",
|
|
74
|
+
description: "Polished Svelte app with Tailwind CSS and sync server"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "svelte-tailwind",
|
|
78
|
+
label: "Svelte 5 + Tailwind (local-only)",
|
|
79
|
+
description: "Polished Svelte app with Tailwind CSS \u2014 no sync server"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "tauri-react",
|
|
83
|
+
label: "Tauri Desktop (native SQLite)",
|
|
84
|
+
description: "Desktop app with native SQLite \u2014 no WASM, includes sync server"
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
|
|
3
88
|
// src/errors.ts
|
|
4
89
|
import { KoraError } from "@korajs/core";
|
|
5
90
|
var CliError = class extends KoraError {
|
|
@@ -8,6 +93,20 @@ var CliError = class extends KoraError {
|
|
|
8
93
|
this.name = "CliError";
|
|
9
94
|
}
|
|
10
95
|
};
|
|
96
|
+
var DeployPlatformUnavailableError = class extends KoraError {
|
|
97
|
+
constructor(platform, available) {
|
|
98
|
+
super(
|
|
99
|
+
`Deploying to "${platform}" is coming soon and not available yet. Choose one of: ${available.join(", ")}. To self-host, run the production server (\`pnpm build && pnpm start\`) in any Node 20+ environment.`,
|
|
100
|
+
"DEPLOY_PLATFORM_UNAVAILABLE",
|
|
101
|
+
{ platform, available }
|
|
102
|
+
);
|
|
103
|
+
this.platform = platform;
|
|
104
|
+
this.available = available;
|
|
105
|
+
this.name = "DeployPlatformUnavailableError";
|
|
106
|
+
}
|
|
107
|
+
platform;
|
|
108
|
+
available;
|
|
109
|
+
};
|
|
11
110
|
var ProjectExistsError = class extends KoraError {
|
|
12
111
|
constructor(directory) {
|
|
13
112
|
super(
|
|
@@ -59,43 +158,6 @@ var DevServerError = class extends KoraError {
|
|
|
59
158
|
searchPath;
|
|
60
159
|
};
|
|
61
160
|
|
|
62
|
-
// src/prompts/preferences.ts
|
|
63
|
-
import Conf from "conf";
|
|
64
|
-
var DEFAULT_PREFERENCES = {
|
|
65
|
-
platform: "web",
|
|
66
|
-
framework: "react",
|
|
67
|
-
tailwind: true,
|
|
68
|
-
sync: true,
|
|
69
|
-
db: "sqlite",
|
|
70
|
-
dbProvider: "none",
|
|
71
|
-
auth: "none",
|
|
72
|
-
packageManager: "pnpm"
|
|
73
|
-
};
|
|
74
|
-
var PREFERENCES_KEY = "create.defaults";
|
|
75
|
-
var PreferenceStore = class {
|
|
76
|
-
store;
|
|
77
|
-
constructor() {
|
|
78
|
-
this.store = new Conf({
|
|
79
|
-
projectName: "korajs-cli"
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
getCreatePreferences() {
|
|
83
|
-
return this.store.get(PREFERENCES_KEY) ?? null;
|
|
84
|
-
}
|
|
85
|
-
saveCreatePreferences(preferences) {
|
|
86
|
-
this.store.set(PREFERENCES_KEY, preferences);
|
|
87
|
-
}
|
|
88
|
-
clearCreatePreferences() {
|
|
89
|
-
this.store.delete(PREFERENCES_KEY);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
function getCreatePreferencesOrDefault(store) {
|
|
93
|
-
return store.getCreatePreferences() ?? DEFAULT_PREFERENCES;
|
|
94
|
-
}
|
|
95
|
-
function getDefaultCreatePreferences() {
|
|
96
|
-
return { ...DEFAULT_PREFERENCES };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
161
|
// src/prompts/prompt-client.ts
|
|
100
162
|
import {
|
|
101
163
|
cancel as clackCancel,
|
|
@@ -272,90 +334,29 @@ var ClackPromptClient = class {
|
|
|
272
334
|
}
|
|
273
335
|
};
|
|
274
336
|
|
|
275
|
-
// src/
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
"vue-tailwind-sync",
|
|
285
|
-
"vue-tailwind",
|
|
286
|
-
"svelte-sync",
|
|
287
|
-
"svelte-basic",
|
|
288
|
-
"svelte-tailwind-sync",
|
|
289
|
-
"svelte-tailwind",
|
|
290
|
-
"tauri-react"
|
|
291
|
-
];
|
|
292
|
-
var TEMPLATE_INFO = [
|
|
293
|
-
{
|
|
294
|
-
name: "react-tailwind-sync",
|
|
295
|
-
label: "React + Tailwind (with sync)",
|
|
296
|
-
description: "Polished dark-themed app with Tailwind CSS and sync server (Recommended)"
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
name: "react-tailwind",
|
|
300
|
-
label: "React + Tailwind (local-only)",
|
|
301
|
-
description: "Polished dark-themed app with Tailwind CSS \u2014 no sync server"
|
|
302
|
-
},
|
|
303
|
-
{
|
|
304
|
-
name: "react-sync",
|
|
305
|
-
label: "React + CSS (with sync)",
|
|
306
|
-
description: "Clean CSS app with sync server included"
|
|
307
|
-
},
|
|
308
|
-
{
|
|
309
|
-
name: "react-basic",
|
|
310
|
-
label: "React + CSS (local-only)",
|
|
311
|
-
description: "Clean CSS app \u2014 no sync server"
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
name: "vue-sync",
|
|
315
|
-
label: "Vue 3 + CSS (with sync)",
|
|
316
|
-
description: "Vue composables with sync server included"
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
name: "vue-basic",
|
|
320
|
-
label: "Vue 3 + CSS (local-only)",
|
|
321
|
-
description: "Vue composables \u2014 no sync server"
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
name: "vue-tailwind-sync",
|
|
325
|
-
label: "Vue 3 + Tailwind (with sync)",
|
|
326
|
-
description: "Polished Vue app with Tailwind CSS and sync server"
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
name: "vue-tailwind",
|
|
330
|
-
label: "Vue 3 + Tailwind (local-only)",
|
|
331
|
-
description: "Polished Vue app with Tailwind CSS \u2014 no sync server"
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
name: "svelte-sync",
|
|
335
|
-
label: "Svelte 5 + CSS (with sync)",
|
|
336
|
-
description: "Svelte stores with sync server included"
|
|
337
|
-
},
|
|
338
|
-
{
|
|
339
|
-
name: "svelte-basic",
|
|
340
|
-
label: "Svelte 5 + CSS (local-only)",
|
|
341
|
-
description: "Svelte stores \u2014 no sync server"
|
|
342
|
-
},
|
|
343
|
-
{
|
|
344
|
-
name: "svelte-tailwind-sync",
|
|
345
|
-
label: "Svelte 5 + Tailwind (with sync)",
|
|
346
|
-
description: "Polished Svelte app with Tailwind CSS and sync server"
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
name: "svelte-tailwind",
|
|
350
|
-
label: "Svelte 5 + Tailwind (local-only)",
|
|
351
|
-
description: "Polished Svelte app with Tailwind CSS \u2014 no sync server"
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
name: "tauri-react",
|
|
355
|
-
label: "Tauri Desktop (native SQLite)",
|
|
356
|
-
description: "Desktop app with native SQLite \u2014 no WASM, includes sync server"
|
|
337
|
+
// src/commands/create/project-name.ts
|
|
338
|
+
import validateNpmPackageName from "validate-npm-package-name";
|
|
339
|
+
function validateProjectName(name) {
|
|
340
|
+
const trimmedName = name.trim();
|
|
341
|
+
if (trimmedName.length === 0) {
|
|
342
|
+
return {
|
|
343
|
+
valid: false,
|
|
344
|
+
issues: ["Project name cannot be empty."]
|
|
345
|
+
};
|
|
357
346
|
}
|
|
358
|
-
|
|
347
|
+
const validation = validateNpmPackageName(trimmedName);
|
|
348
|
+
const issues = [...validation.errors ?? [], ...validation.warnings ?? []];
|
|
349
|
+
if (!validation.validForNewPackages && issues.length === 0) {
|
|
350
|
+
return {
|
|
351
|
+
valid: false,
|
|
352
|
+
issues: ["Project name is not a valid npm package name."]
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
return {
|
|
356
|
+
valid: validation.validForNewPackages,
|
|
357
|
+
issues
|
|
358
|
+
};
|
|
359
|
+
}
|
|
359
360
|
|
|
360
361
|
// src/commands/create/options.ts
|
|
361
362
|
function determineTemplateFromSelections(input) {
|
|
@@ -398,6 +399,43 @@ function isSupportedWebFramework(framework) {
|
|
|
398
399
|
return framework === "react" || framework === "vue" || framework === "svelte";
|
|
399
400
|
}
|
|
400
401
|
|
|
402
|
+
// src/prompts/preferences.ts
|
|
403
|
+
import Conf from "conf";
|
|
404
|
+
var DEFAULT_PREFERENCES = {
|
|
405
|
+
platform: "web",
|
|
406
|
+
framework: "react",
|
|
407
|
+
tailwind: true,
|
|
408
|
+
sync: true,
|
|
409
|
+
db: "sqlite",
|
|
410
|
+
dbProvider: "none",
|
|
411
|
+
auth: "none",
|
|
412
|
+
packageManager: "pnpm"
|
|
413
|
+
};
|
|
414
|
+
var PREFERENCES_KEY = "create.defaults";
|
|
415
|
+
var PreferenceStore = class {
|
|
416
|
+
store;
|
|
417
|
+
constructor() {
|
|
418
|
+
this.store = new Conf({
|
|
419
|
+
projectName: "korajs-cli"
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
getCreatePreferences() {
|
|
423
|
+
return this.store.get(PREFERENCES_KEY) ?? null;
|
|
424
|
+
}
|
|
425
|
+
saveCreatePreferences(preferences) {
|
|
426
|
+
this.store.set(PREFERENCES_KEY, preferences);
|
|
427
|
+
}
|
|
428
|
+
clearCreatePreferences() {
|
|
429
|
+
this.store.delete(PREFERENCES_KEY);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
function getCreatePreferencesOrDefault(store) {
|
|
433
|
+
return store.getCreatePreferences() ?? DEFAULT_PREFERENCES;
|
|
434
|
+
}
|
|
435
|
+
function getDefaultCreatePreferences() {
|
|
436
|
+
return { ...DEFAULT_PREFERENCES };
|
|
437
|
+
}
|
|
438
|
+
|
|
401
439
|
// src/commands/create/preferences-flow.ts
|
|
402
440
|
async function resolveCreatePreferencesFlow(params) {
|
|
403
441
|
const { flags, prompts, store } = params;
|
|
@@ -603,30 +641,6 @@ function formatStoredPreferenceLabel(preferences) {
|
|
|
603
641
|
return `Use previous settings (${preferences.framework} + ${styleLabel} + ${syncLabel} + ${preferences.packageManager})`;
|
|
604
642
|
}
|
|
605
643
|
|
|
606
|
-
// src/commands/create/project-name.ts
|
|
607
|
-
import validateNpmPackageName from "validate-npm-package-name";
|
|
608
|
-
function validateProjectName(name) {
|
|
609
|
-
const trimmedName = name.trim();
|
|
610
|
-
if (trimmedName.length === 0) {
|
|
611
|
-
return {
|
|
612
|
-
valid: false,
|
|
613
|
-
issues: ["Project name cannot be empty."]
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
const validation = validateNpmPackageName(trimmedName);
|
|
617
|
-
const issues = [...validation.errors ?? [], ...validation.warnings ?? []];
|
|
618
|
-
if (!validation.validForNewPackages && issues.length === 0) {
|
|
619
|
-
return {
|
|
620
|
-
valid: false,
|
|
621
|
-
issues: ["Project name is not a valid npm package name."]
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
return {
|
|
625
|
-
valid: validation.validForNewPackages,
|
|
626
|
-
issues
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
|
|
630
644
|
// src/commands/create/sync-provider-preset.ts
|
|
631
645
|
import { readFile, writeFile } from "fs/promises";
|
|
632
646
|
import { join } from "path";
|
|
@@ -749,33 +763,34 @@ function createLogger(options) {
|
|
|
749
763
|
}
|
|
750
764
|
|
|
751
765
|
export {
|
|
752
|
-
|
|
766
|
+
PACKAGE_MANAGERS,
|
|
767
|
+
TEMPLATES,
|
|
768
|
+
TEMPLATE_INFO,
|
|
753
769
|
CliError,
|
|
770
|
+
DeployPlatformUnavailableError,
|
|
754
771
|
ProjectExistsError,
|
|
755
772
|
SchemaNotFoundError,
|
|
756
773
|
InvalidProjectError,
|
|
757
774
|
DevServerError,
|
|
758
|
-
|
|
759
|
-
getCreatePreferencesOrDefault,
|
|
760
|
-
getDefaultCreatePreferences,
|
|
775
|
+
createLogger,
|
|
761
776
|
promptConfirm,
|
|
762
777
|
PromptCancelledError,
|
|
763
778
|
ReadlinePromptClient,
|
|
764
779
|
createPromptClient,
|
|
765
780
|
ClackPromptClient,
|
|
766
|
-
|
|
767
|
-
TEMPLATES,
|
|
768
|
-
TEMPLATE_INFO,
|
|
781
|
+
validateProjectName,
|
|
769
782
|
determineTemplateFromSelections,
|
|
770
783
|
isFrameworkValue,
|
|
771
784
|
isAuthValue,
|
|
772
785
|
isDatabaseValue,
|
|
773
786
|
isDatabaseProviderValue,
|
|
774
787
|
isSupportedWebFramework,
|
|
788
|
+
PreferenceStore,
|
|
789
|
+
getCreatePreferencesOrDefault,
|
|
790
|
+
getDefaultCreatePreferences,
|
|
775
791
|
resolveCreatePreferencesFlow,
|
|
776
792
|
shouldSavePreferences,
|
|
777
793
|
saveResolvedPreferences,
|
|
778
|
-
validateProjectName,
|
|
779
794
|
applySyncProviderPreset
|
|
780
795
|
};
|
|
781
|
-
//# sourceMappingURL=chunk-
|
|
796
|
+
//# sourceMappingURL=chunk-7Y4J2GXP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/errors.ts","../src/prompts/prompt-client.ts","../src/utils/prompt.ts","../src/commands/create/project-name.ts","../src/commands/create/options.ts","../src/prompts/preferences.ts","../src/commands/create/preferences-flow.ts","../src/commands/create/sync-provider-preset.ts","../src/utils/logger.ts"],"sourcesContent":["/** Supported package managers */\nexport const PACKAGE_MANAGERS = ['pnpm', 'npm', 'yarn', 'bun'] as const\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number]\n\n/** Available project templates */\nexport const TEMPLATES = [\n\t'react-tailwind-sync',\n\t'react-tailwind',\n\t'react-sync',\n\t'react-basic',\n\t'vue-sync',\n\t'vue-basic',\n\t'vue-tailwind-sync',\n\t'vue-tailwind',\n\t'svelte-sync',\n\t'svelte-basic',\n\t'svelte-tailwind-sync',\n\t'svelte-tailwind',\n\t'tauri-react',\n] as const\nexport type TemplateName = (typeof TEMPLATES)[number]\n\n/** Metadata for a project template */\nexport interface TemplateInfo {\n\tname: TemplateName\n\tlabel: string\n\tdescription: string\n}\n\n/** Available templates with their descriptions */\nexport const TEMPLATE_INFO: readonly TemplateInfo[] = [\n\t{\n\t\tname: 'react-tailwind-sync',\n\t\tlabel: 'React + Tailwind (with sync)',\n\t\tdescription: 'Polished dark-themed app with Tailwind CSS and sync server (Recommended)',\n\t},\n\t{\n\t\tname: 'react-tailwind',\n\t\tlabel: 'React + Tailwind (local-only)',\n\t\tdescription: 'Polished dark-themed app with Tailwind CSS — no sync server',\n\t},\n\t{\n\t\tname: 'react-sync',\n\t\tlabel: 'React + CSS (with sync)',\n\t\tdescription: 'Clean CSS app with sync server included',\n\t},\n\t{\n\t\tname: 'react-basic',\n\t\tlabel: 'React + CSS (local-only)',\n\t\tdescription: 'Clean CSS app — no sync server',\n\t},\n\t{\n\t\tname: 'vue-sync',\n\t\tlabel: 'Vue 3 + CSS (with sync)',\n\t\tdescription: 'Vue composables with sync server included',\n\t},\n\t{\n\t\tname: 'vue-basic',\n\t\tlabel: 'Vue 3 + CSS (local-only)',\n\t\tdescription: 'Vue composables — no sync server',\n\t},\n\t{\n\t\tname: 'vue-tailwind-sync',\n\t\tlabel: 'Vue 3 + Tailwind (with sync)',\n\t\tdescription: 'Polished Vue app with Tailwind CSS and sync server',\n\t},\n\t{\n\t\tname: 'vue-tailwind',\n\t\tlabel: 'Vue 3 + Tailwind (local-only)',\n\t\tdescription: 'Polished Vue app with Tailwind CSS — no sync server',\n\t},\n\t{\n\t\tname: 'svelte-sync',\n\t\tlabel: 'Svelte 5 + CSS (with sync)',\n\t\tdescription: 'Svelte stores with sync server included',\n\t},\n\t{\n\t\tname: 'svelte-basic',\n\t\tlabel: 'Svelte 5 + CSS (local-only)',\n\t\tdescription: 'Svelte stores — no sync server',\n\t},\n\t{\n\t\tname: 'svelte-tailwind-sync',\n\t\tlabel: 'Svelte 5 + Tailwind (with sync)',\n\t\tdescription: 'Polished Svelte app with Tailwind CSS and sync server',\n\t},\n\t{\n\t\tname: 'svelte-tailwind',\n\t\tlabel: 'Svelte 5 + Tailwind (local-only)',\n\t\tdescription: 'Polished Svelte app with Tailwind CSS — no sync server',\n\t},\n\t{\n\t\tname: 'tauri-react',\n\t\tlabel: 'Tauri Desktop (native SQLite)',\n\t\tdescription: 'Desktop app with native SQLite — no WASM, includes sync server',\n\t},\n] as const\n\n/** Variables available for template substitution */\nexport interface TemplateContext {\n\tprojectName: string\n\tpackageManager: PackageManager\n\tkoraVersion: string\n\t/** `@korajs/tauri` version for the desktop template (its own version line). */\n\ttauriVersion?: string\n\tdbProvider?: string\n}\n","import { KoraError } from '@korajs/core'\n\n/**\n * Base error class for all CLI errors.\n */\nexport class CliError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'CLI_ERROR', context)\n\t\tthis.name = 'CliError'\n\t}\n}\n\n/**\n * Thrown when `kora deploy` targets a platform whose adapter is not implemented yet\n * (DX-8). Raised before any artifact or deploy state is written.\n */\nexport class DeployPlatformUnavailableError extends KoraError {\n\tconstructor(\n\t\tpublic readonly platform: string,\n\t\tpublic readonly available: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Deploying to \"${platform}\" is coming soon and not available yet. Choose one of: ${available.join(', ')}. To self-host, run the production server (\\`pnpm build && pnpm start\\`) in any Node 20+ environment.`,\n\t\t\t'DEPLOY_PLATFORM_UNAVAILABLE',\n\t\t\t{ platform, available },\n\t\t)\n\t\tthis.name = 'DeployPlatformUnavailableError'\n\t}\n}\n\n/**\n * Thrown when the target project directory already exists.\n */\nexport class ProjectExistsError extends KoraError {\n\tconstructor(public readonly directory: string) {\n\t\tsuper(\n\t\t\t`Directory \"${directory}\" already exists. Choose a different name or remove the existing directory.`,\n\t\t\t'PROJECT_EXISTS',\n\t\t\t{ directory },\n\t\t)\n\t\tthis.name = 'ProjectExistsError'\n\t}\n}\n\n/**\n * Thrown when a schema file cannot be found in the project.\n */\nexport class SchemaNotFoundError extends KoraError {\n\tconstructor(public readonly searchedPaths: string[]) {\n\t\tsuper(\n\t\t\t`Could not find a schema file. Searched: ${searchedPaths.join(', ')}. Create a schema file using defineSchema() from @korajs/core.`,\n\t\t\t'SCHEMA_NOT_FOUND',\n\t\t\t{ searchedPaths },\n\t\t)\n\t\tthis.name = 'SchemaNotFoundError'\n\t}\n}\n\n/**\n * Thrown when a command is run outside a valid Kora project.\n */\nexport class InvalidProjectError extends KoraError {\n\tconstructor(public readonly directory: string) {\n\t\tsuper(\n\t\t\t`\"${directory}\" is not a valid Kora project. No package.json with a kora dependency found. Run this command from inside a Kora project.`,\n\t\t\t'INVALID_PROJECT',\n\t\t\t{ directory },\n\t\t)\n\t\tthis.name = 'InvalidProjectError'\n\t}\n}\n\n/**\n * Thrown when a required local dev server binary cannot be found.\n */\nexport class DevServerError extends KoraError {\n\tconstructor(\n\t\tpublic readonly binary: string,\n\t\tpublic readonly searchPath: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not find required binary \"${binary}\" at ${searchPath}. Install project dependencies and try again.`,\n\t\t\t'DEV_SERVER_ERROR',\n\t\t\t{ binary, searchPath },\n\t\t)\n\t\tthis.name = 'DevServerError'\n\t}\n}\n","import {\n\tcancel as clackCancel,\n\tconfirm as clackConfirm,\n\tintro as clackIntro,\n\tisCancel as clackIsCancel,\n\toutro as clackOutro,\n\tselect as clackSelect,\n\ttext as clackText,\n} from '@clack/prompts'\nimport { promptConfirm, promptSelect, promptText } from '../utils/prompt'\n\nexport interface SelectOption<T extends string> {\n\tlabel: string\n\tvalue: T\n\thint?: string\n\tdisabled?: boolean\n}\n\ntype ClackSelectOption<T extends string> = {\n\tvalue: T\n\tlabel?: string\n\thint?: string\n\tdisabled?: boolean\n}\n\nexport interface PromptClient {\n\ttext(message: string, defaultValue?: string): Promise<string>\n\tselect<T extends string>(message: string, options: readonly SelectOption<T>[]): Promise<T>\n\tconfirm(message: string, defaultValue?: boolean): Promise<boolean>\n\tintro(message: string): void\n\toutro(message: string): void\n}\n\nexport class PromptCancelledError extends Error {\n\tpublic constructor(message = 'Prompt cancelled by user') {\n\t\tsuper(message)\n\t\tthis.name = 'PromptCancelledError'\n\t}\n}\n\n/**\n * Prompt client backed by the current readline helpers.\n *\n * Phase 12 will introduce a richer prompt backend. This adapter keeps command\n * logic decoupled from the prompt implementation so we can migrate without\n * reshaping command behavior.\n */\nexport class ReadlinePromptClient implements PromptClient {\n\tpublic async text(message: string, defaultValue?: string): Promise<string> {\n\t\treturn promptText(message, defaultValue)\n\t}\n\n\tpublic async select<T extends string>(\n\t\tmessage: string,\n\t\toptions: readonly SelectOption<T>[],\n\t): Promise<T> {\n\t\treturn promptSelect(\n\t\t\tmessage,\n\t\t\toptions\n\t\t\t\t.filter((option) => option.disabled !== true)\n\t\t\t\t.map((option) => ({ label: option.label, value: option.value })),\n\t\t)\n\t}\n\n\tpublic async confirm(message: string, defaultValue = false): Promise<boolean> {\n\t\treturn promptConfirm(message, defaultValue)\n\t}\n\n\tpublic intro(message: string): void {\n\t\t// The readline backend does not provide intro/outro framing.\n\t\t// Keep no-op semantics for compatibility.\n\t\tvoid message\n\t}\n\n\tpublic outro(message: string): void {\n\t\t// The readline backend does not provide intro/outro framing.\n\t\t// Keep no-op semantics for compatibility.\n\t\tvoid message\n\t}\n}\n\n/**\n * Returns the default prompt client for interactive CLI flows.\n */\nexport function createPromptClient(): PromptClient {\n\tconst canUseInteractiveClack =\n\t\ttypeof process !== 'undefined' && process.stdin.isTTY && process.stdout.isTTY\n\tif (canUseInteractiveClack) {\n\t\treturn new ClackPromptClient()\n\t}\n\treturn new ReadlinePromptClient()\n}\n\n/**\n * Prompt client backed by @clack/prompts for richer interactive UX.\n * Falls back to readline in non-interactive contexts.\n */\nexport class ClackPromptClient implements PromptClient {\n\tpublic async text(message: string, defaultValue?: string): Promise<string> {\n\t\tconst result = await clackText({\n\t\t\tmessage,\n\t\t\tplaceholder: defaultValue,\n\t\t\tdefaultValue,\n\t\t})\n\t\tif (clackIsCancel(result)) {\n\t\t\tclackCancel('Operation cancelled.')\n\t\t\tthrow new PromptCancelledError()\n\t\t}\n\t\tconst value = result.trim()\n\t\tif (value.length > 0) return value\n\t\treturn defaultValue ?? ''\n\t}\n\n\tpublic async select<T extends string>(\n\t\tmessage: string,\n\t\toptions: readonly SelectOption<T>[],\n\t): Promise<T> {\n\t\tconst mappedOptions: ClackSelectOption<T>[] = options.map((option) => ({\n\t\t\tlabel: option.label,\n\t\t\tvalue: option.value,\n\t\t\thint: option.hint,\n\t\t\tdisabled: option.disabled,\n\t\t}))\n\t\tconst result = await clackSelect({\n\t\t\tmessage,\n\t\t\toptions: mappedOptions as unknown as Parameters<typeof clackSelect>[0]['options'],\n\t\t})\n\t\tif (clackIsCancel(result)) {\n\t\t\tclackCancel('Operation cancelled.')\n\t\t\tthrow new PromptCancelledError()\n\t\t}\n\t\treturn result as T\n\t}\n\n\tpublic async confirm(message: string, defaultValue = false): Promise<boolean> {\n\t\tconst result = await clackConfirm({\n\t\t\tmessage,\n\t\t\tinitialValue: defaultValue,\n\t\t})\n\t\tif (clackIsCancel(result)) {\n\t\t\tclackCancel('Operation cancelled.')\n\t\t\tthrow new PromptCancelledError()\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic intro(message: string): void {\n\t\tclackIntro(message)\n\t}\n\n\tpublic outro(message: string): void {\n\t\tclackOutro(message)\n\t}\n}\n","import { type Interface as ReadlineInterface, createInterface } from 'node:readline'\n\nexport interface PromptOptions {\n\t/** Input stream (defaults to process.stdin) */\n\tinput?: NodeJS.ReadableStream\n\t/** Output stream (defaults to process.stdout) */\n\toutput?: NodeJS.WritableStream\n}\n\n/**\n * Prompts the user for text input.\n *\n * @param message - The prompt message to display\n * @param defaultValue - Optional default value shown in brackets\n * @param options - Optional input/output streams for testing\n */\nexport function promptText(\n\tmessage: string,\n\tdefaultValue?: string,\n\toptions?: PromptOptions,\n): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createReadline(options)\n\t\tconst suffix = defaultValue !== undefined ? ` (${defaultValue})` : ''\n\t\trl.question(` ? ${message}${suffix}: `, (answer) => {\n\t\t\trl.close()\n\t\t\tconst trimmed = answer.trim()\n\t\t\tresolve(trimmed || defaultValue || '')\n\t\t})\n\t})\n}\n\n/**\n * Prompts the user to select from a numbered list of options.\n *\n * @param message - The prompt message to display\n * @param choices - Array of { label, value } options\n * @param options - Optional input/output streams for testing\n */\nexport function promptSelect<T extends string>(\n\tmessage: string,\n\tchoices: readonly { label: string; value: T }[],\n\toptions?: PromptOptions,\n): Promise<T> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createReadline(options)\n\t\tconst out = options?.output ?? process.stdout\n\n\t\tout.write(` ? ${message}\\n`)\n\t\tfor (let i = 0; i < choices.length; i++) {\n\t\t\tconst choice = choices[i]\n\t\t\tif (choice) {\n\t\t\t\tout.write(` ${i + 1}) ${choice.label}\\n`)\n\t\t\t}\n\t\t}\n\n\t\tconst ask = (): void => {\n\t\t\trl.question(' > ', (answer) => {\n\t\t\t\tconst index = Number.parseInt(answer.trim(), 10) - 1\n\t\t\t\tconst selected = choices[index]\n\t\t\t\tif (selected) {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(selected.value)\n\t\t\t\t} else {\n\t\t\t\t\tout.write(` Please enter a number between 1 and ${choices.length}\\n`)\n\t\t\t\t\task()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\task()\n\t})\n}\n\n/**\n * Prompts the user with a yes/no confirmation.\n *\n * @param message - The prompt message to display\n * @param defaultValue - Default when input is empty (true => yes)\n * @param options - Optional input/output streams for testing\n */\nexport function promptConfirm(\n\tmessage: string,\n\tdefaultValue = false,\n\toptions?: PromptOptions,\n): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createReadline(options)\n\t\tconst suffix = defaultValue ? 'Y/n' : 'y/N'\n\n\t\tconst ask = (): void => {\n\t\t\trl.question(` ? ${message} (${suffix}): `, (answer) => {\n\t\t\t\tconst normalized = answer.trim().toLowerCase()\n\t\t\t\tif (normalized.length === 0) {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(defaultValue)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (normalized === 'y' || normalized === 'yes') {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (normalized === 'n' || normalized === 'no') {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t;(options?.output ?? process.stdout).write(' Please answer with y or n\\n')\n\t\t\t\task()\n\t\t\t})\n\t\t}\n\n\t\task()\n\t})\n}\n\nfunction createReadline(options?: PromptOptions): ReadlineInterface {\n\treturn createInterface({\n\t\tinput: options?.input ?? process.stdin,\n\t\toutput: options?.output ?? process.stdout,\n\t})\n}\n","import validateNpmPackageName from 'validate-npm-package-name'\n\nexport interface ProjectNameValidationResult {\n\tvalid: boolean\n\tissues: readonly string[]\n}\n\n/**\n * Validates a project name for scaffolded package creation.\n *\n * The create command uses this validation before writing files so users get a\n * clear, early error if the name cannot be used as an npm package name.\n */\nexport function validateProjectName(name: string): ProjectNameValidationResult {\n\tconst trimmedName = name.trim()\n\tif (trimmedName.length === 0) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\tissues: ['Project name cannot be empty.'],\n\t\t}\n\t}\n\n\tconst validation = validateNpmPackageName(trimmedName)\n\tconst issues = [...(validation.errors ?? []), ...(validation.warnings ?? [])]\n\tif (!validation.validForNewPackages && issues.length === 0) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\tissues: ['Project name is not a valid npm package name.'],\n\t\t}\n\t}\n\n\treturn {\n\t\tvalid: validation.validForNewPackages,\n\t\tissues,\n\t}\n}\n","import type { TemplateName } from '../../types'\n\nexport type PlatformOption = 'web' | 'desktop-tauri'\nexport type FrameworkOption = 'react' | 'vue' | 'svelte' | 'solid'\nexport type AuthOption = 'none' | 'email-password' | 'oauth'\nexport type DatabaseOption = 'none' | 'sqlite' | 'postgres'\nexport type DatabaseProviderOption =\n\t| 'none'\n\t| 'local'\n\t| 'supabase'\n\t| 'neon'\n\t| 'railway'\n\t| 'vercel-postgres'\n\t| 'custom'\n\nexport interface TemplateSelectionInput {\n\tplatform: PlatformOption\n\tframework: FrameworkOption\n\ttailwind: boolean\n\tsync: boolean\n\tdb: DatabaseOption\n}\n\n/**\n * Converts high-level scaffold selections into a concrete template name.\n */\nexport function determineTemplateFromSelections(input: TemplateSelectionInput): TemplateName {\n\tif (input.platform === 'desktop-tauri') return 'tauri-react'\n\n\tconst shouldSync = input.sync && input.db !== 'none'\n\n\tif (input.framework === 'vue') {\n\t\tif (input.tailwind && shouldSync) return 'vue-tailwind-sync'\n\t\tif (input.tailwind && !shouldSync) return 'vue-tailwind'\n\t\treturn shouldSync ? 'vue-sync' : 'vue-basic'\n\t}\n\n\tif (input.framework === 'svelte') {\n\t\tif (input.tailwind && shouldSync) return 'svelte-tailwind-sync'\n\t\tif (input.tailwind && !shouldSync) return 'svelte-tailwind'\n\t\treturn shouldSync ? 'svelte-sync' : 'svelte-basic'\n\t}\n\n\tif (input.framework === 'solid') {\n\t\tthrow new Error('Solid templates are not available yet. Use react, vue, or svelte.')\n\t}\n\n\tif (input.tailwind && shouldSync) return 'react-tailwind-sync'\n\tif (input.tailwind && !shouldSync) return 'react-tailwind'\n\tif (!input.tailwind && shouldSync) return 'react-sync'\n\treturn 'react-basic'\n}\n\nexport function isPlatformValue(value: string): value is PlatformOption {\n\treturn value === 'web' || value === 'desktop-tauri'\n}\n\nexport function isFrameworkValue(value: string): value is FrameworkOption {\n\treturn value === 'react' || value === 'vue' || value === 'svelte' || value === 'solid'\n}\n\nexport function isAuthValue(value: string): value is AuthOption {\n\treturn value === 'none' || value === 'email-password' || value === 'oauth'\n}\n\nexport function isDatabaseValue(value: string): value is DatabaseOption {\n\treturn value === 'none' || value === 'sqlite' || value === 'postgres'\n}\n\nexport function isDatabaseProviderValue(value: string): value is DatabaseProviderOption {\n\treturn (\n\t\tvalue === 'none' ||\n\t\tvalue === 'local' ||\n\t\tvalue === 'supabase' ||\n\t\tvalue === 'neon' ||\n\t\tvalue === 'railway' ||\n\t\tvalue === 'vercel-postgres' ||\n\t\tvalue === 'custom'\n\t)\n}\n\nexport function isSupportedWebFramework(framework: FrameworkOption): boolean {\n\treturn framework === 'react' || framework === 'vue' || framework === 'svelte'\n}\n","import Conf from 'conf'\nimport type {\n\tAuthOption,\n\tDatabaseOption,\n\tDatabaseProviderOption,\n\tFrameworkOption,\n\tPlatformOption,\n} from '../commands/create/options'\nimport type { PackageManager } from '../types'\n\nexport interface CreatePreferences {\n\tplatform: PlatformOption\n\tframework: FrameworkOption\n\ttailwind: boolean\n\tsync: boolean\n\tdb: DatabaseOption\n\tdbProvider: DatabaseProviderOption\n\tauth: AuthOption\n\tpackageManager: PackageManager\n}\n\nconst DEFAULT_PREFERENCES: CreatePreferences = {\n\tplatform: 'web',\n\tframework: 'react',\n\ttailwind: true,\n\tsync: true,\n\tdb: 'sqlite',\n\tdbProvider: 'none',\n\tauth: 'none',\n\tpackageManager: 'pnpm',\n}\n\nconst PREFERENCES_KEY = 'create.defaults'\n\n/**\n * Preference store for scaffold-time defaults in `create-kora-app`.\n */\nexport class PreferenceStore {\n\tprivate readonly store: Conf<{ [PREFERENCES_KEY]?: CreatePreferences }>\n\n\tpublic constructor() {\n\t\tthis.store = new Conf<{ [PREFERENCES_KEY]?: CreatePreferences }>({\n\t\t\tprojectName: 'korajs-cli',\n\t\t})\n\t}\n\n\tpublic getCreatePreferences(): CreatePreferences | null {\n\t\treturn this.store.get(PREFERENCES_KEY) ?? null\n\t}\n\n\tpublic saveCreatePreferences(preferences: CreatePreferences): void {\n\t\tthis.store.set(PREFERENCES_KEY, preferences)\n\t}\n\n\tpublic clearCreatePreferences(): void {\n\t\tthis.store.delete(PREFERENCES_KEY)\n\t}\n}\n\n/**\n * Gets preferences from storage or returns defaults when not available.\n */\nexport function getCreatePreferencesOrDefault(store: PreferenceStore): CreatePreferences {\n\treturn store.getCreatePreferences() ?? DEFAULT_PREFERENCES\n}\n\nexport function getDefaultCreatePreferences(): CreatePreferences {\n\treturn { ...DEFAULT_PREFERENCES }\n}\n","import {\n\ttype CreatePreferences,\n\ttype PreferenceStore,\n\tgetCreatePreferencesOrDefault,\n\tgetDefaultCreatePreferences,\n} from '../../prompts/preferences'\nimport type { PromptClient } from '../../prompts/prompt-client'\nimport {\n\ttype AuthOption,\n\ttype DatabaseOption,\n\ttype DatabaseProviderOption,\n\ttype FrameworkOption,\n\ttype PlatformOption,\n\tdetermineTemplateFromSelections,\n\tisAuthValue,\n\tisDatabaseProviderValue,\n\tisDatabaseValue,\n\tisFrameworkValue,\n\tisPlatformValue,\n} from './options'\n\nexport interface CreateFlags {\n\tplatform?: string\n\tframework?: string\n\tauth?: string\n\tdb?: string\n\tdbProvider?: string\n\ttailwind?: boolean\n\tsync?: boolean\n\tuseDefaults: boolean\n}\n\nexport interface PreferenceResolutionResult {\n\tplatform: PlatformOption\n\tframework: FrameworkOption\n\tauth: AuthOption\n\tdb: DatabaseOption\n\tdbProvider: DatabaseProviderOption\n\ttailwind: boolean\n\tsync: boolean\n\ttemplate: ReturnType<typeof determineTemplateFromSelections>\n\tusedStoredPreferences: boolean\n}\n\n/**\n * Resolves scaffold options with precedence:\n * CLI flags > --yes defaults > stored preferences > interactive prompts.\n */\nexport async function resolveCreatePreferencesFlow(params: {\n\tflags: CreateFlags\n\tprompts: PromptClient\n\tstore: PreferenceStore\n}): Promise<PreferenceResolutionResult> {\n\tconst { flags, prompts, store } = params\n\tconst stored = store.getCreatePreferences()\n\tconst base = getCreatePreferencesOrDefault(store)\n\tconst hasExplicitFlags = hasExplicitPreferenceFlags(flags)\n\tconst canOfferStored =\n\t\t!flags.useDefaults && !hasExplicitFlags && stored !== null && promptSupportsRichOptions()\n\n\tlet effective: CreatePreferences = { ...base }\n\tlet usedStoredPreferences = false\n\n\tif (flags.useDefaults) {\n\t\teffective = getDefaultCreatePreferences()\n\t} else if (canOfferStored && stored !== null) {\n\t\tconst reuseStored = await prompts.select('Welcome back! Choose setup mode:', [\n\t\t\t{ label: formatStoredPreferenceLabel(stored), value: 'reuse' },\n\t\t\t{ label: 'Customize', value: 'customize' },\n\t\t])\n\t\tif (reuseStored === 'reuse') {\n\t\t\teffective = { ...stored }\n\t\t\tusedStoredPreferences = true\n\t\t}\n\t}\n\n\tif (flags.platform !== undefined) {\n\t\tif (!isPlatformValue(flags.platform)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid --platform value \"${flags.platform}\". Expected one of: web, desktop-tauri.`,\n\t\t\t)\n\t\t}\n\t\teffective.platform = flags.platform\n\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\teffective.platform = await prompts.select('Platform:', [\n\t\t\t{ label: 'Web (browser)', value: 'web' },\n\t\t\t{ label: 'Desktop (Tauri — native SQLite)', value: 'desktop-tauri' },\n\t\t])\n\t}\n\n\tconst isTauri = effective.platform === 'desktop-tauri'\n\n\tif (isTauri) {\n\t\t// Tauri currently uses React and native SQLite on the client.\n\t\t// The sync server remains configurable so the same desktop scaffold can\n\t\t// run local-only, LAN sync, or cloud sync without switching templates.\n\t\teffective.framework = 'react'\n\t\teffective.tailwind = false\n\t\teffective.auth = 'none'\n\n\t\tif (flags.sync !== undefined) {\n\t\t\teffective.sync = flags.sync\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.sync = await prompts.confirm('Enable multi-device sync?', true)\n\t\t}\n\n\t\tif (flags.db !== undefined) {\n\t\t\tif (!isDatabaseValue(flags.db)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db value \"${flags.db}\". Expected one of: none, sqlite, postgres.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.db = flags.db\n\t\t} else if (!effective.sync) {\n\t\t\teffective.db = 'none'\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.db = await prompts.select('Sync server database:', [\n\t\t\t\t{ label: 'SQLite (zero-config; local, LAN, small teams)', value: 'sqlite' },\n\t\t\t\t{ label: 'PostgreSQL (production-scale)', value: 'postgres' },\n\t\t\t])\n\t\t}\n\n\t\tif (effective.db === 'none') {\n\t\t\teffective.sync = false\n\t\t}\n\n\t\tif (effective.db !== 'postgres') {\n\t\t\teffective.dbProvider = 'none'\n\t\t} else if (flags.dbProvider !== undefined) {\n\t\t\tif (!isDatabaseProviderValue(flags.dbProvider)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db-provider value \"${flags.dbProvider}\". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.dbProvider = flags.dbProvider\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.dbProvider = await prompts.select('Database provider:', [\n\t\t\t\t{ label: 'Local Postgres', value: 'local' },\n\t\t\t\t{ label: 'Supabase', value: 'supabase' },\n\t\t\t\t{ label: 'Neon', value: 'neon' },\n\t\t\t\t{ label: 'Railway', value: 'railway' },\n\t\t\t\t{ label: 'Vercel Postgres', value: 'vercel-postgres' },\n\t\t\t\t{ label: 'Custom connection string', value: 'custom' },\n\t\t\t])\n\t\t}\n\t} else {\n\t\tif (flags.framework !== undefined) {\n\t\t\tif (!isFrameworkValue(flags.framework)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --framework value \"${flags.framework}\". Expected one of: react, vue, svelte, solid.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.framework = flags.framework\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.framework = await prompts.select('UI framework:', [\n\t\t\t\t{ label: 'React', value: 'react' },\n\t\t\t\t{ label: 'Vue 3', value: 'vue' },\n\t\t\t\t{ label: 'Svelte 5', value: 'svelte' },\n\t\t\t\t{ label: 'Solid (coming soon)', value: 'solid', disabled: true },\n\t\t\t])\n\t\t}\n\n\t\tif (flags.auth !== undefined) {\n\t\t\tif (!isAuthValue(flags.auth)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --auth value \"${flags.auth}\". Expected one of: none, email-password, oauth.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.auth = flags.auth\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.auth = await prompts.select('Authentication:', [\n\t\t\t\t{ label: 'None', value: 'none' },\n\t\t\t\t{ label: 'Email + Password (coming soon)', value: 'email-password', disabled: true },\n\t\t\t\t{ label: 'OAuth (coming soon)', value: 'oauth', disabled: true },\n\t\t\t])\n\t\t}\n\n\t\tif (flags.tailwind !== undefined) {\n\t\t\teffective.tailwind = flags.tailwind\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.tailwind = await prompts.confirm('Use Tailwind CSS?', true)\n\t\t}\n\n\t\tif (flags.sync !== undefined) {\n\t\t\teffective.sync = flags.sync\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.sync = await prompts.confirm('Enable multi-device sync?', true)\n\t\t}\n\n\t\tif (flags.db !== undefined) {\n\t\t\tif (!isDatabaseValue(flags.db)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db value \"${flags.db}\". Expected one of: none, sqlite, postgres.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.db = flags.db\n\t\t} else if (!effective.sync) {\n\t\t\teffective.db = 'none'\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.db = await prompts.select('Server-side database:', [\n\t\t\t\t{ label: 'SQLite (zero-config)', value: 'sqlite' },\n\t\t\t\t{ label: 'PostgreSQL (production-scale)', value: 'postgres' },\n\t\t\t])\n\t\t}\n\n\t\tif (effective.db !== 'postgres') {\n\t\t\teffective.dbProvider = 'none'\n\t\t} else if (flags.dbProvider !== undefined) {\n\t\t\tif (!isDatabaseProviderValue(flags.dbProvider)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db-provider value \"${flags.dbProvider}\". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.dbProvider = flags.dbProvider\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.dbProvider = await prompts.select('Database provider:', [\n\t\t\t\t{ label: 'Local Postgres', value: 'local' },\n\t\t\t\t{ label: 'Supabase', value: 'supabase' },\n\t\t\t\t{ label: 'Neon', value: 'neon' },\n\t\t\t\t{ label: 'Railway', value: 'railway' },\n\t\t\t\t{ label: 'Vercel Postgres', value: 'vercel-postgres' },\n\t\t\t\t{ label: 'Custom connection string', value: 'custom' },\n\t\t\t])\n\t\t}\n\t}\n\n\tconst template = determineTemplateFromSelections({\n\t\tplatform: effective.platform,\n\t\tframework: effective.framework,\n\t\ttailwind: effective.tailwind,\n\t\tsync: effective.sync,\n\t\tdb: effective.db,\n\t})\n\n\treturn {\n\t\tplatform: effective.platform,\n\t\tframework: effective.framework,\n\t\tauth: effective.auth,\n\t\tdb: effective.db,\n\t\tdbProvider: effective.dbProvider,\n\t\ttailwind: effective.tailwind,\n\t\tsync: effective.sync,\n\t\ttemplate,\n\t\tusedStoredPreferences,\n\t}\n}\n\nexport function shouldSavePreferences(flags: CreateFlags): boolean {\n\treturn !flags.useDefaults\n}\n\nexport function saveResolvedPreferences(\n\tstore: PreferenceStore,\n\tresolution: Omit<PreferenceResolutionResult, 'template' | 'usedStoredPreferences'> & {\n\t\tpackageManager: CreatePreferences['packageManager']\n\t},\n): void {\n\tstore.saveCreatePreferences({\n\t\tplatform: resolution.platform,\n\t\tframework: resolution.framework,\n\t\ttailwind: resolution.tailwind,\n\t\tsync: resolution.sync,\n\t\tdb: resolution.db,\n\t\tdbProvider: resolution.dbProvider,\n\t\tauth: resolution.auth,\n\t\tpackageManager: resolution.packageManager,\n\t})\n}\n\nfunction hasExplicitPreferenceFlags(flags: CreateFlags): boolean {\n\treturn (\n\t\tflags.platform !== undefined ||\n\t\tflags.framework !== undefined ||\n\t\tflags.auth !== undefined ||\n\t\tflags.db !== undefined ||\n\t\tflags.dbProvider !== undefined ||\n\t\tflags.tailwind !== undefined ||\n\t\tflags.sync !== undefined\n\t)\n}\n\nfunction promptSupportsRichOptions(): boolean {\n\treturn typeof process !== 'undefined' && process.stdin.isTTY && process.stdout.isTTY\n}\n\nfunction formatStoredPreferenceLabel(preferences: CreatePreferences): string {\n\tif (preferences.platform === 'desktop-tauri') {\n\t\treturn `Use previous settings (tauri-desktop + ${preferences.packageManager})`\n\t}\n\tconst syncLabel = preferences.sync ? `sync/${preferences.db}` : 'local-only'\n\tconst styleLabel = preferences.tailwind ? 'tailwind' : 'css'\n\treturn `Use previous settings (${preferences.framework} + ${styleLabel} + ${syncLabel} + ${preferences.packageManager})`\n}\n","import { readFile, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { TemplateName } from '../../types'\nimport type { DatabaseOption, DatabaseProviderOption } from './options'\n\ninterface SyncProviderPresetOptions {\n\ttargetDir: string\n\ttemplate: TemplateName\n\tdb: DatabaseOption\n\tdbProvider: DatabaseProviderOption\n}\n\n/**\n * Applies provider-specific sync scaffolding adjustments after template copy.\n *\n * The sync server template is environment-driven: SQLite is used when\n * DATABASE_URL is absent, and PostgreSQL is used when DATABASE_URL is present.\n * Provider presets only add provider-specific guidance.\n */\nexport async function applySyncProviderPreset(options: SyncProviderPresetOptions): Promise<void> {\n\tif (!isSyncTemplate(options.template)) {\n\t\treturn\n\t}\n\tif (options.db !== 'postgres') {\n\t\treturn\n\t}\n\n\tconst providerName = getProviderDisplayName(options.dbProvider)\n\tconst providerConnectionString = getProviderConnectionStringExample(options.dbProvider)\n\tconst envPath = join(options.targetDir, '.env.example')\n\tconst readmePath = join(options.targetDir, 'README.md')\n\n\tconst existingReadme = await readFile(readmePath, 'utf-8')\n\tconst existingEnv = await readFile(envPath, 'utf-8')\n\tconst trimmedReadme = existingReadme.trimEnd()\n\tconst trimmedEnv = existingEnv.trimEnd()\n\tconst envSuffix = [\n\t\t'',\n\t\t`# PostgreSQL provider preset: ${providerName}`,\n\t\t`# Example: ${providerConnectionString}`,\n\t].join('\\n')\n\tconst readmeSuffix = [\n\t\t'',\n\t\t'## PostgreSQL Provider Preset',\n\t\t'',\n\t\t`Selected DB provider: ${options.dbProvider}`,\n\t\t'',\n\t\t'This scaffold keeps one sync server entrypoint. When `DATABASE_URL` is set, `server.ts` uses PostgreSQL. When it is empty, the same server uses SQLite at `KORA_SERVER_DB`.',\n\t\t'',\n\t\t'The generated server uses `createPostgresServerStore` automatically when `DATABASE_URL` is present.',\n\t\t'',\n\t].join('\\n')\n\tconst readmeTemplate = `${trimmedReadme}${readmeSuffix}`\n\n\tawait writeFile(envPath, `${trimmedEnv}${envSuffix}\\n`, 'utf-8')\n\tawait writeFile(readmePath, readmeTemplate, 'utf-8')\n}\n\nfunction isSyncTemplate(template: TemplateName): boolean {\n\treturn (\n\t\ttemplate === 'react-sync' ||\n\t\ttemplate === 'react-tailwind-sync' ||\n\t\ttemplate === 'vue-sync' ||\n\t\ttemplate === 'vue-tailwind-sync' ||\n\t\ttemplate === 'svelte-sync' ||\n\t\ttemplate === 'svelte-tailwind-sync' ||\n\t\ttemplate === 'tauri-react'\n\t)\n}\n\nfunction getProviderDisplayName(provider: DatabaseProviderOption): string {\n\tswitch (provider) {\n\t\tcase 'supabase':\n\t\t\treturn 'Supabase'\n\t\tcase 'neon':\n\t\t\treturn 'Neon'\n\t\tcase 'railway':\n\t\t\treturn 'Railway'\n\t\tcase 'vercel-postgres':\n\t\t\treturn 'Vercel Postgres'\n\t\tcase 'custom':\n\t\t\treturn 'Custom'\n\t\tcase 'local':\n\t\t\treturn 'Local Postgres'\n\t\tcase 'none':\n\t\t\treturn 'PostgreSQL'\n\t}\n}\n\nfunction getProviderConnectionStringExample(provider: DatabaseProviderOption): string {\n\tswitch (provider) {\n\t\tcase 'supabase':\n\t\t\treturn 'postgresql://postgres:<password>@db.<project-ref>.supabase.co:5432/postgres?sslmode=require'\n\t\tcase 'neon':\n\t\t\treturn 'postgresql://<user>:<password>@<branch>.<project>.neon.tech/neondb?sslmode=require'\n\t\tcase 'railway':\n\t\t\treturn 'postgresql://postgres:<password>@<host>.railway.app:<port>/railway?sslmode=require'\n\t\tcase 'vercel-postgres':\n\t\t\treturn 'postgresql://<user>:<password>@<host>.pooler.vercel-storage.com:5432/verceldb?sslmode=require'\n\t\tcase 'custom':\n\t\t\treturn 'postgresql://<user>:<password>@<host>:5432/<database>'\n\t\tcase 'local':\n\t\t\treturn 'postgresql://postgres:postgres@localhost:5432/kora'\n\t\tcase 'none':\n\t\t\treturn 'postgresql://postgres:postgres@localhost:5432/kora'\n\t}\n}\n","/** ANSI escape codes for terminal colors */\nconst RESET = '\\x1b[0m'\nconst BOLD = '\\x1b[1m'\nconst DIM = '\\x1b[2m'\nconst GREEN = '\\x1b[32m'\nconst YELLOW = '\\x1b[33m'\nconst RED = '\\x1b[31m'\nconst CYAN = '\\x1b[36m'\n\nexport interface LoggerOptions {\n\t/** Disable ANSI colors */\n\tnoColor?: boolean\n}\n\nexport interface Logger {\n\tinfo(message: string): void\n\tsuccess(message: string): void\n\twarn(message: string): void\n\terror(message: string): void\n\tstep(message: string): void\n\tblank(): void\n\tbanner(): void\n}\n\n/**\n * Creates a logger with optional ANSI color support.\n * Respects the NO_COLOR environment variable and TTY detection.\n */\nexport function createLogger(options?: LoggerOptions): Logger {\n\tconst colorDisabled =\n\t\toptions?.noColor === true || process.env.NO_COLOR !== undefined || !process.stdout.isTTY\n\n\tfunction color(code: string, text: string): string {\n\t\treturn colorDisabled ? text : `${code}${text}${RESET}`\n\t}\n\n\treturn {\n\t\tinfo(message: string): void {\n\t\t\tconsole.log(color(CYAN, message))\n\t\t},\n\t\tsuccess(message: string): void {\n\t\t\tconsole.log(color(GREEN, ` ✓ ${message}`))\n\t\t},\n\t\twarn(message: string): void {\n\t\t\tconsole.warn(color(YELLOW, ` ⚠ ${message}`))\n\t\t},\n\t\terror(message: string): void {\n\t\t\tconsole.error(color(RED, ` ✗ ${message}`))\n\t\t},\n\t\tstep(message: string): void {\n\t\t\tconsole.log(color(DIM, ` ${message}`))\n\t\t},\n\t\tblank(): void {\n\t\t\tconsole.log()\n\t\t},\n\t\tbanner(): void {\n\t\t\tconsole.log()\n\t\t\tconsole.log(\n\t\t\t\tcolor(BOLD + CYAN, ' Kora.js') + color(DIM, ', the offline-first application framework'),\n\t\t\t)\n\t\t\tconsole.log()\n\t\t},\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
saveResolvedPreferences,
|
|
14
14
|
shouldSavePreferences,
|
|
15
15
|
validateProjectName
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-7Y4J2GXP.js";
|
|
17
17
|
import {
|
|
18
18
|
directoryExists
|
|
19
19
|
} from "./chunk-5NI2FEQL.js";
|
|
@@ -164,11 +164,42 @@ async function findNearestAncestorWithEntry(startDir, entryName) {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
// src/commands/create/pnpm-workspace.ts
|
|
168
|
+
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
169
|
+
import { join as join2 } from "path";
|
|
170
|
+
async function writePnpmWorkspaceSettings(targetDir) {
|
|
171
|
+
const manifest = JSON.parse(await readFile2(join2(targetDir, "package.json"), "utf-8"));
|
|
172
|
+
const listed = manifest.pnpm?.onlyBuiltDependencies;
|
|
173
|
+
const allowed = Array.isArray(listed) ? [...new Set(listed.filter((name) => typeof name === "string"))].sort() : [];
|
|
174
|
+
await writeFile2(join2(targetDir, "pnpm-workspace.yaml"), renderPnpmWorkspace(allowed), "utf-8");
|
|
175
|
+
return allowed;
|
|
176
|
+
}
|
|
177
|
+
function renderPnpmWorkspace(allowed) {
|
|
178
|
+
const quote = (name) => `'${name.replace(/'/g, "''")}'`;
|
|
179
|
+
const lines = [
|
|
180
|
+
"# pnpm settings for this app. Dependencies listed here may run their install",
|
|
181
|
+
"# (build) scripts: pnpm 10 reads onlyBuiltDependencies, pnpm 11+ reads allowBuilds.",
|
|
182
|
+
"packages:",
|
|
183
|
+
" - '.'"
|
|
184
|
+
];
|
|
185
|
+
if (allowed.length > 0) {
|
|
186
|
+
lines.push("onlyBuiltDependencies:", ...allowed.map((name) => ` - ${quote(name)}`));
|
|
187
|
+
lines.push("allowBuilds:", ...allowed.map((name) => ` ${quote(name)}: true`));
|
|
188
|
+
}
|
|
189
|
+
return `${lines.join("\n")}
|
|
190
|
+
`;
|
|
191
|
+
}
|
|
192
|
+
|
|
167
193
|
// src/templates/composer.ts
|
|
168
194
|
import { existsSync } from "fs";
|
|
169
|
-
import { copyFile, mkdir as mkdir2, readFile as
|
|
170
|
-
import { dirname as dirname2, join as
|
|
195
|
+
import { copyFile, mkdir as mkdir2, readFile as readFile3, readdir, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
196
|
+
import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
|
|
171
197
|
import { fileURLToPath } from "url";
|
|
198
|
+
|
|
199
|
+
// src/templates/tauri-version.ts
|
|
200
|
+
var KORA_TAURI_TEMPLATE_VERSION = "0.4.3-beta.13";
|
|
201
|
+
|
|
202
|
+
// src/templates/composer.ts
|
|
172
203
|
function substituteVariables(template, context) {
|
|
173
204
|
return template.replace(/\{\{(\w+)\}\}/g, (_match, key) => {
|
|
174
205
|
const value = context[key];
|
|
@@ -307,6 +338,7 @@ async function composeTemplateLayers(plan, targetDir, context) {
|
|
|
307
338
|
projectName: context.projectName,
|
|
308
339
|
packageManager: context.packageManager,
|
|
309
340
|
koraVersion: context.koraVersion,
|
|
341
|
+
tauriVersion: context.tauriVersion ?? KORA_TAURI_TEMPLATE_VERSION,
|
|
310
342
|
dbProvider: context.dbProvider ?? "none"
|
|
311
343
|
};
|
|
312
344
|
for (const layer of plan.layers) {
|
|
@@ -321,19 +353,19 @@ async function copyDirectory(src, dest, vars) {
|
|
|
321
353
|
await mkdir2(dest, { recursive: true });
|
|
322
354
|
const entries = await readdir(src);
|
|
323
355
|
for (const entry of entries) {
|
|
324
|
-
const srcPath =
|
|
356
|
+
const srcPath = join3(src, entry);
|
|
325
357
|
const srcStat = await stat2(srcPath);
|
|
326
358
|
if (srcStat.isDirectory()) {
|
|
327
|
-
await copyDirectory(srcPath,
|
|
359
|
+
await copyDirectory(srcPath, join3(dest, entry), vars);
|
|
328
360
|
continue;
|
|
329
361
|
}
|
|
330
362
|
if (entry.endsWith(".hbs")) {
|
|
331
|
-
const content = await
|
|
363
|
+
const content = await readFile3(srcPath, "utf-8");
|
|
332
364
|
const outputName = entry.slice(0, -4);
|
|
333
|
-
await
|
|
365
|
+
await writeFile3(join3(dest, outputName), substituteVariables(content, vars), "utf-8");
|
|
334
366
|
continue;
|
|
335
367
|
}
|
|
336
|
-
await copyFile(srcPath,
|
|
368
|
+
await copyFile(srcPath, join3(dest, entry));
|
|
337
369
|
}
|
|
338
370
|
}
|
|
339
371
|
|
|
@@ -512,6 +544,9 @@ var createCommand = defineCommand({
|
|
|
512
544
|
db: selection.db,
|
|
513
545
|
dbProvider: selection.dbProvider
|
|
514
546
|
});
|
|
547
|
+
if (pm === "pnpm") {
|
|
548
|
+
await writePnpmWorkspaceSettings(targetDir);
|
|
549
|
+
}
|
|
515
550
|
if (!useDefaults && editorDetection.editor !== "unknown") {
|
|
516
551
|
const shouldApplyEditorPreset = await prompts.confirm(
|
|
517
552
|
`Detected ${formatEditor(editorDetection.editor)}. Add workspace recommendations for ${formatEditor(editorDetection.editor)}?`,
|
|
@@ -681,4 +716,4 @@ function deriveKoraTemplateVersion(version) {
|
|
|
681
716
|
export {
|
|
682
717
|
createCommand
|
|
683
718
|
};
|
|
684
|
-
//# sourceMappingURL=chunk-
|
|
719
|
+
//# sourceMappingURL=chunk-BURFQVMV.js.map
|