kavoru 0.9.6 → 0.9.8
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 +1 -1
- package/package.json +1 -1
- package/src/args.ts +1 -1
- package/src/features.ts +45 -2
- package/src/prompts.ts +11 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ bunx kavoru@latest my-api
|
|
|
38
38
|
| `--no-install` | Skip `bun install` |
|
|
39
39
|
| `--repo owner/name` | Override template repo (default: `mertthesamael/Kavoru`) |
|
|
40
40
|
| `--branch name` | Template branch (default: `master`) |
|
|
41
|
-
| `--minimal` |
|
|
41
|
+
| `--minimal` | Optional integrations off (Docker Compose + Project CLI always included) |
|
|
42
42
|
| `--features list` | Comma-separated features to include |
|
|
43
43
|
| `--no-features list`| Comma-separated features to exclude (default: all on) |
|
|
44
44
|
|
package/package.json
CHANGED
package/src/args.ts
CHANGED
|
@@ -32,7 +32,7 @@ Options:
|
|
|
32
32
|
--no-install Skip "bun install" after scaffolding
|
|
33
33
|
--repo <owner/name> GitHub template repo (default: mertthesamael/Kavoru)
|
|
34
34
|
--branch <name> Template branch (default: master)
|
|
35
|
-
--minimal Core only (
|
|
35
|
+
--minimal Core optional integrations only (Docker + Project CLI always included)
|
|
36
36
|
--features <list> Comma-separated features to include (default: all)
|
|
37
37
|
--no-features <list> Comma-separated features to exclude
|
|
38
38
|
|
package/src/features.ts
CHANGED
|
@@ -17,6 +17,19 @@ export type FeatureId =
|
|
|
17
17
|
/** Always scaffolded — not a CLI toggle. */
|
|
18
18
|
export const ALWAYS_INCLUDED = ["docker", "cli"] as const;
|
|
19
19
|
|
|
20
|
+
export const MANDATORY_FEATURE_DEFS = [
|
|
21
|
+
{
|
|
22
|
+
id: "docker",
|
|
23
|
+
label: "Docker Compose",
|
|
24
|
+
description: "docker-compose.yaml + app image",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "cli",
|
|
28
|
+
label: "Project CLI",
|
|
29
|
+
description: "kavoru module command, bin, shims",
|
|
30
|
+
},
|
|
31
|
+
] as const;
|
|
32
|
+
|
|
20
33
|
const FEATURE_ALIASES: Record<string, FeatureId> = {
|
|
21
34
|
prisma: "postgres",
|
|
22
35
|
};
|
|
@@ -288,9 +301,12 @@ export function parseFeatureExcludeList(
|
|
|
288
301
|
}
|
|
289
302
|
|
|
290
303
|
export function formatFeatureSelection(selection: FeatureSelection): string {
|
|
304
|
+
const mandatory = ALWAYS_INCLUDED.join(", ");
|
|
291
305
|
const enabled = enabledFeatures(selection);
|
|
292
|
-
if (enabled.length === 0)
|
|
293
|
-
|
|
306
|
+
if (enabled.length === 0) {
|
|
307
|
+
return `${mandatory} · optional: none`;
|
|
308
|
+
}
|
|
309
|
+
return `${mandatory} · optional: ${enabled.join(", ")}`;
|
|
294
310
|
}
|
|
295
311
|
|
|
296
312
|
async function removePaths(projectDir: string, relativePaths: string[]) {
|
|
@@ -316,6 +332,31 @@ async function writeText(
|
|
|
316
332
|
await Bun.write(path.join(projectDir, relativePath), content);
|
|
317
333
|
}
|
|
318
334
|
|
|
335
|
+
export async function regenerateRouteRegistry(projectDir: string): Promise<void> {
|
|
336
|
+
const modulesDir = path.join(projectDir, "src/modules");
|
|
337
|
+
const glob = new Bun.Glob("*/routes.ts");
|
|
338
|
+
const files = [...glob.scanSync(modulesDir)]
|
|
339
|
+
.map((file) => file.replaceAll("\\", "/"))
|
|
340
|
+
.sort();
|
|
341
|
+
|
|
342
|
+
const imports = files
|
|
343
|
+
.map((file, index) => {
|
|
344
|
+
const modulePath = `./${file.replace(/\.ts$/, "")}`;
|
|
345
|
+
return `import * as route${index} from "${modulePath}";`;
|
|
346
|
+
})
|
|
347
|
+
.join("\n");
|
|
348
|
+
|
|
349
|
+
const registry = files.map((_, index) => `route${index}`).join(", ");
|
|
350
|
+
|
|
351
|
+
const content = `// Auto-generated by scripts/generate-route-registry.ts — do not edit
|
|
352
|
+
${imports}
|
|
353
|
+
|
|
354
|
+
export const routeModules = [${registry}];
|
|
355
|
+
`;
|
|
356
|
+
|
|
357
|
+
await writeText(projectDir, "src/modules/routes.registry.ts", content);
|
|
358
|
+
}
|
|
359
|
+
|
|
319
360
|
function removeImportLines(content: string, modules: string[]) {
|
|
320
361
|
let next = content;
|
|
321
362
|
for (const modulePath of modules) {
|
|
@@ -1010,6 +1051,8 @@ export async function applyFeatures(
|
|
|
1010
1051
|
await removePaths(projectDir, FEATURE_PATHS[featureId]);
|
|
1011
1052
|
}
|
|
1012
1053
|
|
|
1054
|
+
await regenerateRouteRegistry(projectDir);
|
|
1055
|
+
|
|
1013
1056
|
await patchModulesIndex(projectDir, selection);
|
|
1014
1057
|
await patchEntryIndex(projectDir, selection);
|
|
1015
1058
|
await patchServerIndex(projectDir, selection);
|
package/src/prompts.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { stdin, stdout } from "node:process";
|
|
|
2
2
|
import {
|
|
3
3
|
ALL_FEATURES,
|
|
4
4
|
FEATURES,
|
|
5
|
+
MANDATORY_FEATURE_DEFS,
|
|
5
6
|
MINIMAL_FEATURES,
|
|
6
7
|
normalizeFeatureSelection,
|
|
7
8
|
type FeatureId,
|
|
@@ -84,10 +85,19 @@ function renderCheckboxMenu(
|
|
|
84
85
|
): number {
|
|
85
86
|
const lines: string[] = [
|
|
86
87
|
`${cyan}◆${reset} Select optional features ${dim}(↑↓ move · Space toggle · Enter confirm)${reset}`,
|
|
87
|
-
`${dim} a = all · m = minimal${reset}`,
|
|
88
|
+
`${dim} a = all · m = minimal optional only${reset}`,
|
|
88
89
|
"",
|
|
90
|
+
`${dim}Always included:${reset}`,
|
|
89
91
|
];
|
|
90
92
|
|
|
93
|
+
for (const feature of MANDATORY_FEATURE_DEFS) {
|
|
94
|
+
lines.push(
|
|
95
|
+
` [x] ${feature.label.padEnd(22)} ${dim}${feature.description}${reset}`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
lines.push("", `${dim}Optional:${reset}`);
|
|
100
|
+
|
|
91
101
|
FEATURES.forEach((feature, index) => {
|
|
92
102
|
const isActive = index === activeIndex;
|
|
93
103
|
const pointer = isActive ? `${cyan}❯${reset}` : " ";
|