kavoru 0.9.7 → 0.9.9
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 +79 -31
- 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[]) {
|
|
@@ -479,41 +495,73 @@ async function patchEntryIndex(
|
|
|
479
495
|
await writeText(projectDir, "src/index.ts", buildEntryIndex(selection));
|
|
480
496
|
}
|
|
481
497
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
498
|
+
export function buildServerIndex(selection: FeatureSelection): string {
|
|
499
|
+
const imports = [
|
|
500
|
+
'import { Elysia } from "elysia";',
|
|
501
|
+
'import { config } from "../config/index";',
|
|
502
|
+
'import { logger } from "../common/logger";',
|
|
503
|
+
'import { registerModules } from "../modules";',
|
|
504
|
+
selection.cron ? 'import { schedules } from "../schedules";' : null,
|
|
505
|
+
]
|
|
506
|
+
.filter(Boolean)
|
|
507
|
+
.join("\n");
|
|
489
508
|
|
|
490
|
-
|
|
509
|
+
const elysiaCtor = selection.websocket
|
|
510
|
+
? `new Elysia({
|
|
511
|
+
websocket: {
|
|
512
|
+
idleTimeout: 120,
|
|
513
|
+
},
|
|
514
|
+
})`
|
|
515
|
+
: "new Elysia()";
|
|
516
|
+
|
|
517
|
+
const uses = [
|
|
518
|
+
" .use(registerModules)",
|
|
519
|
+
selection.cron ? " .use(schedules)" : null,
|
|
520
|
+
]
|
|
521
|
+
.filter(Boolean)
|
|
522
|
+
.join("\n");
|
|
491
523
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
} else {
|
|
502
|
-
content = content.replace(
|
|
503
|
-
/^import \{ schedules \} from "\.\.\/schedules";\n/m,
|
|
504
|
-
"",
|
|
505
|
-
);
|
|
506
|
-
content = content.replace(/^\s*\.use\(schedules\);\n/m, "");
|
|
524
|
+
return `${imports}
|
|
525
|
+
|
|
526
|
+
export class HttpServer {
|
|
527
|
+
private app: any;
|
|
528
|
+
private server?: ReturnType<Elysia["listen"]>;
|
|
529
|
+
|
|
530
|
+
constructor() {
|
|
531
|
+
this.app = ${elysiaCtor}
|
|
532
|
+
${uses};
|
|
507
533
|
}
|
|
508
534
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
535
|
+
async start() {
|
|
536
|
+
if (this.server) return;
|
|
537
|
+
|
|
538
|
+
await this.app.modules;
|
|
539
|
+
|
|
540
|
+
this.server = this.app.listen(config.env.server.port, () => {
|
|
541
|
+
logger.info(
|
|
542
|
+
\`API ready on port \${config.env.server.port}. Version: \${config.version}\`,
|
|
543
|
+
);
|
|
544
|
+
});
|
|
514
545
|
}
|
|
515
546
|
|
|
516
|
-
|
|
547
|
+
async stop() {
|
|
548
|
+
if (!this.server) return;
|
|
549
|
+
this.server.stop();
|
|
550
|
+
this.server = undefined;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
`;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
async function patchServerIndex(
|
|
557
|
+
projectDir: string,
|
|
558
|
+
selection: FeatureSelection,
|
|
559
|
+
) {
|
|
560
|
+
await writeText(
|
|
561
|
+
projectDir,
|
|
562
|
+
"src/server/index.ts",
|
|
563
|
+
buildServerIndex(selection),
|
|
564
|
+
);
|
|
517
565
|
}
|
|
518
566
|
|
|
519
567
|
async function patchPackageJson(
|
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}` : " ";
|