kavoru 0.3.0 → 0.5.0
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 +21 -9
- package/package.json +1 -1
- package/src/args.ts +4 -4
- package/src/cli.ts +1 -1
- package/src/constants.ts +3 -1
- package/src/features.ts +37 -20
package/README.md
CHANGED
|
@@ -7,12 +7,24 @@ Scaffold a new [Kavoru](https://github.com/mertthesamael/Kavoru) backend — Ely
|
|
|
7
7
|
After publishing to npm:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
bunx kavoru my-api
|
|
10
|
+
bunx kavoru@latest my-api
|
|
11
11
|
cd my-api
|
|
12
12
|
bun run dev
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Always use `@latest` so you get the newest published CLI. Equivalent to `bunx --bun kavoru@latest`.
|
|
16
|
+
|
|
17
|
+
**Stale CLI after a new publish?** Bun caches `bunx` installs under `%TEMP%\bunx-*-kavoru@latest` and does not auto-refresh. Clear the cache, then run `@latest` again:
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
Remove-Item -Recurse -Force "$env:TEMP\bunx-*-kavoru*"
|
|
21
|
+
bunx kavoru@latest my-api
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
rm -rf "${TMPDIR:-/tmp}"/bunx-*-kavoru*
|
|
26
|
+
bunx kavoru@latest my-api
|
|
27
|
+
```
|
|
16
28
|
|
|
17
29
|
### Options
|
|
18
30
|
|
|
@@ -50,22 +62,22 @@ Interactive mode (TTY) shows a checkbox menu (↑↓ move, Space toggle, Enter c
|
|
|
50
62
|
|
|
51
63
|
```bash
|
|
52
64
|
# Interactive (prompts for project name + feature toggles)
|
|
53
|
-
bunx kavoru
|
|
65
|
+
bunx kavoru@latest
|
|
54
66
|
|
|
55
67
|
# Current directory
|
|
56
|
-
bunx kavoru .
|
|
68
|
+
bunx kavoru@latest .
|
|
57
69
|
|
|
58
70
|
# Minimal API skeleton
|
|
59
|
-
bunx kavoru my-api --minimal
|
|
71
|
+
bunx kavoru@latest my-api --minimal
|
|
60
72
|
|
|
61
73
|
# Pick specific features
|
|
62
|
-
bunx kavoru my-api --features auth,prisma,otel,sentry
|
|
74
|
+
bunx kavoru@latest my-api --features auth,prisma,otel,sentry
|
|
63
75
|
|
|
64
76
|
# Full stack minus Kafka and Docker
|
|
65
|
-
bunx kavoru my-api --no-features kafka,docker
|
|
77
|
+
bunx kavoru@latest my-api --no-features kafka,docker
|
|
66
78
|
|
|
67
79
|
# Custom template fork (local dev)
|
|
68
|
-
bunx kavoru demo --repo your-user/Kavoru --no-install
|
|
80
|
+
bunx kavoru@latest demo --repo your-user/Kavoru --no-install
|
|
69
81
|
```
|
|
70
82
|
|
|
71
83
|
## Development
|
|
@@ -79,7 +91,7 @@ bun test
|
|
|
79
91
|
bun run src/index.ts my-test-app
|
|
80
92
|
# or
|
|
81
93
|
bun link
|
|
82
|
-
bunx kavoru my-test-app
|
|
94
|
+
bunx kavoru@latest my-test-app
|
|
83
95
|
```
|
|
84
96
|
|
|
85
97
|
## License
|
package/package.json
CHANGED
package/src/args.ts
CHANGED
|
@@ -36,10 +36,10 @@ Features:
|
|
|
36
36
|
auth, prisma, otel, sentry, kafka, websocket, resend, cron, docker
|
|
37
37
|
|
|
38
38
|
Examples:
|
|
39
|
-
bunx kavoru my-api
|
|
40
|
-
bunx kavoru my-api --minimal
|
|
41
|
-
bunx kavoru my-api --features auth,prisma,otel
|
|
42
|
-
bunx kavoru my-api --no-features kafka,docker,resend
|
|
39
|
+
bunx kavoru@latest my-api
|
|
40
|
+
bunx kavoru@latest my-api --minimal
|
|
41
|
+
bunx kavoru@latest my-api --features auth,prisma,otel
|
|
42
|
+
bunx kavoru@latest my-api --no-features kafka,docker,resend
|
|
43
43
|
`;
|
|
44
44
|
|
|
45
45
|
export function parseArgs(argv: string[]): CliOptions {
|
package/src/cli.ts
CHANGED
|
@@ -97,7 +97,7 @@ export async function runCli(options: CliOptions): Promise<void> {
|
|
|
97
97
|
if (!targetArg) {
|
|
98
98
|
const interactive = process.stdin.isTTY && process.stdout.isTTY;
|
|
99
99
|
if (!interactive) {
|
|
100
|
-
throw new Error("Missing project directory. Usage: bunx kavoru <directory>");
|
|
100
|
+
throw new Error("Missing project directory. Usage: bunx kavoru@latest <directory>");
|
|
101
101
|
}
|
|
102
102
|
targetArg = await promptProjectName();
|
|
103
103
|
}
|
package/src/constants.ts
CHANGED
package/src/features.ts
CHANGED
|
@@ -504,40 +504,60 @@ async function patchDockerfile(projectDir: string, selection: FeatureSelection)
|
|
|
504
504
|
let content = current;
|
|
505
505
|
if (!selection.prisma) {
|
|
506
506
|
content = content.replace(/^\s*COPY prisma\.config\.ts \.\/.*\n/m, "");
|
|
507
|
-
content = content.replace(
|
|
508
|
-
|
|
509
|
-
|
|
507
|
+
content = content.replace(
|
|
508
|
+
/^\s*# generate only needs the schema on disk, not a live database\n/m,
|
|
509
|
+
"",
|
|
510
|
+
);
|
|
511
|
+
content = content.replace(
|
|
512
|
+
/^\s*RUN if \[ -f src\/infra\/prisma\/schemas\/schema\.prisma \]; then bunx prisma generate; fi\n/m,
|
|
513
|
+
"",
|
|
514
|
+
);
|
|
510
515
|
}
|
|
511
516
|
|
|
512
517
|
await writeText(projectDir, relativePath, content);
|
|
513
518
|
}
|
|
514
519
|
|
|
520
|
+
function buildAppEnvironment(selection: FeatureSelection): string {
|
|
521
|
+
const lines = [" NODE_ENV: production"];
|
|
522
|
+
if (selection.kafka) {
|
|
523
|
+
lines.push(" KAFKA_BROKERS: kafka:9092");
|
|
524
|
+
}
|
|
525
|
+
if (selection.otel) {
|
|
526
|
+
lines.push(" OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318/v1/traces");
|
|
527
|
+
}
|
|
528
|
+
return ` environment:\n${lines.join("\n")}\n`;
|
|
529
|
+
}
|
|
530
|
+
|
|
515
531
|
function generateDockerCompose(selection: FeatureSelection): string {
|
|
516
532
|
const appDependsOn = selection.kafka
|
|
517
533
|
? ` depends_on:
|
|
518
534
|
kafka:
|
|
519
535
|
condition: service_started
|
|
520
|
-
environment:
|
|
521
|
-
KAFKA_BROKERS: kafka:9092
|
|
522
536
|
`
|
|
523
537
|
: "";
|
|
538
|
+
const appEnvironment = buildAppEnvironment(selection);
|
|
524
539
|
|
|
525
540
|
const kafkaService = selection.kafka
|
|
526
541
|
? `
|
|
527
542
|
kafka:
|
|
528
|
-
image:
|
|
543
|
+
image: confluentinc/cp-kafka:7.6.1
|
|
544
|
+
hostname: kafka
|
|
529
545
|
ports:
|
|
530
546
|
- "9094:9094"
|
|
531
547
|
environment:
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
548
|
+
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
|
|
549
|
+
KAFKA_NODE_ID: "0"
|
|
550
|
+
KAFKA_PROCESS_ROLES: broker,controller
|
|
551
|
+
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
|
|
552
|
+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094
|
|
553
|
+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT
|
|
554
|
+
KAFKA_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093
|
|
555
|
+
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
|
556
|
+
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
|
557
|
+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
|
558
|
+
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
|
|
559
|
+
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
|
|
560
|
+
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
|
|
541
561
|
networks:
|
|
542
562
|
- app_network
|
|
543
563
|
restart: unless-stopped
|
|
@@ -547,7 +567,7 @@ function generateDockerCompose(selection: FeatureSelection): string {
|
|
|
547
567
|
const jaegerService = selection.otel
|
|
548
568
|
? `
|
|
549
569
|
jaeger:
|
|
550
|
-
image: jaegertracing/all-in-one:1.62
|
|
570
|
+
image: jaegertracing/all-in-one:1.62.0
|
|
551
571
|
ports:
|
|
552
572
|
- "16686:16686"
|
|
553
573
|
- "4318:4318"
|
|
@@ -580,7 +600,7 @@ function generateDockerCompose(selection: FeatureSelection): string {
|
|
|
580
600
|
restart: unless-stopped
|
|
581
601
|
env_file:
|
|
582
602
|
- .env
|
|
583
|
-
${appDependsOn} healthcheck:
|
|
603
|
+
${appDependsOn}${appEnvironment} healthcheck:
|
|
584
604
|
test: ["CMD", "curl", "-f", "http://localhost:\${PORT}/healthz"]
|
|
585
605
|
interval: 600s
|
|
586
606
|
timeout: 300s
|
|
@@ -589,10 +609,7 @@ ${appDependsOn} healthcheck:
|
|
|
589
609
|
${kafkaService}${jaegerService}
|
|
590
610
|
networks:
|
|
591
611
|
app_network:
|
|
592
|
-
name: app_network
|
|
593
612
|
driver: bridge
|
|
594
|
-
|
|
595
|
-
version: "3.8"
|
|
596
613
|
`;
|
|
597
614
|
}
|
|
598
615
|
|