rapidkit 0.25.6 → 0.25.7
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.
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import {promises}from'fs';import r from'path';var g="1.24",i="github.com/air-verse/air@v1.52.3",a="github.com/swaggo/swag/cmd/swag@v1.16.3",n="main.go -d cmd/server,internal/handlers,internal/apierr -o docs --parseDependency";function u(e){return e.split(/[-_\s]+/).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}async function $(e,t){await promises.mkdir(r.dirname(e),{recursive:true}),await promises.writeFile(e,t,"utf8");}function h(e){let t=e.includeLintAndFmt?`
|
|
2
|
+
lint:
|
|
3
|
+
@command -v golangci-lint >/dev/null 2>&1 || (echo "golangci-lint not found. Install: https://golangci-lint.run/usage/install/" && exit 1)
|
|
4
|
+
golangci-lint run ./...
|
|
5
|
+
|
|
6
|
+
fmt:
|
|
7
|
+
gofmt -w .
|
|
8
|
+
`:"";return `.PHONY: dev run build test cover${e.includeLintAndFmt?" lint fmt":""} tidy docs docker-up docker-down
|
|
9
|
+
|
|
10
|
+
# Build-time metadata
|
|
11
|
+
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
|
12
|
+
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "none")
|
|
13
|
+
DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
14
|
+
LDFLAGS = -ldflags "-s -w -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.date=$(DATE)"
|
|
15
|
+
# Go tool binaries are installed to GOPATH/bin; include it so \`air\` and \`swag\` are found.
|
|
16
|
+
GOBIN ?= $(shell go env GOPATH)/bin
|
|
17
|
+
|
|
18
|
+
# Hot reload \u2014 installs pinned air version on first use
|
|
19
|
+
dev:
|
|
20
|
+
@test -x "$(GOBIN)/air" || go install ${i}
|
|
21
|
+
${e.devCommand}
|
|
22
|
+
|
|
23
|
+
run:
|
|
24
|
+
${e.runCommand}
|
|
25
|
+
|
|
26
|
+
build:
|
|
27
|
+
go build $(LDFLAGS) -o bin/${e.projectName} ./cmd/server
|
|
28
|
+
|
|
29
|
+
test:
|
|
30
|
+
${e.testCommand}
|
|
31
|
+
|
|
32
|
+
cover:
|
|
33
|
+
${e.testCommand.replace("./... -v -race","./... -race -coverprofile=coverage.out").replace("GIN_MODE=test ","GIN_MODE=test ")}
|
|
34
|
+
go tool cover -html=coverage.out -o coverage.html
|
|
35
|
+
@echo "Coverage report: coverage.html"
|
|
36
|
+
|
|
37
|
+
# Generate Swagger docs \u2014 installs pinned swag version on first use
|
|
38
|
+
docs:
|
|
39
|
+
@test -x "$(GOBIN)/swag" || go install ${a}
|
|
40
|
+
$(GOBIN)/swag init -g ${n}${t}
|
|
41
|
+
tidy:
|
|
42
|
+
go mod tidy
|
|
43
|
+
|
|
44
|
+
docker-up:
|
|
45
|
+
go mod tidy
|
|
46
|
+
docker compose up --build \\
|
|
47
|
+
--build-arg VERSION=$(VERSION) \\
|
|
48
|
+
--build-arg COMMIT=$(COMMIT) \\
|
|
49
|
+
--build-arg DATE=$(DATE) \\
|
|
50
|
+
-d
|
|
51
|
+
|
|
52
|
+
docker-down:
|
|
53
|
+
docker compose down
|
|
54
|
+
`}function p(e){return `#!/usr/bin/env sh
|
|
55
|
+
# RapidKit ${e.runtimeLabel} project launcher \u2014 generated by RapidKit CLI
|
|
56
|
+
# https://getrapidkit.com
|
|
57
|
+
|
|
58
|
+
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
59
|
+
CMD="\${1:-}"
|
|
60
|
+
shift 2>/dev/null || true
|
|
61
|
+
|
|
62
|
+
case "$CMD" in
|
|
63
|
+
init)
|
|
64
|
+
cd "$SCRIPT_DIR"
|
|
65
|
+
echo "\u{1F439} Initializing ${e.runtimeLabel} project\u2026"
|
|
66
|
+
GOBIN="$(go env GOPATH)/bin"
|
|
67
|
+
echo " \u2192 installing air (hot reload)\u2026"
|
|
68
|
+
go install ${i} 2>/dev/null && echo " \u2713 air" || echo " \u26A0 air install failed (run: go install ${i})"
|
|
69
|
+
echo " \u2192 installing swag (swagger)\u2026"
|
|
70
|
+
go install ${a} 2>/dev/null && echo " \u2713 swag" || echo " \u26A0 swag install failed (run: go install ${a})"
|
|
71
|
+
if [ ! -f ".env" ] && [ -f ".env.example" ]; then
|
|
72
|
+
cp .env.example .env && echo " \u2713 .env created from .env.example"
|
|
73
|
+
fi
|
|
74
|
+
go mod tidy && echo " \u2713 go mod tidy"
|
|
75
|
+
echo " \u2192 generating swagger docs (first build)\u2026"
|
|
76
|
+
"$(go env GOPATH)/bin/swag" init -g ${n} 2>/dev/null \\
|
|
77
|
+
&& echo " \u2713 swagger docs generated" \\
|
|
78
|
+
|| echo " \u26A0 swagger docs skipped (run: rapidkit docs)"
|
|
79
|
+
echo "\u2705 Ready \u2014 run: rapidkit dev"
|
|
80
|
+
;;
|
|
81
|
+
dev)
|
|
82
|
+
cd "$SCRIPT_DIR"
|
|
83
|
+
echo "\u{1F4D6} Syncing swagger docs\u2026"
|
|
84
|
+
"$(go env GOPATH)/bin/swag" init -g ${n} 2>/dev/null || true
|
|
85
|
+
if [ -f "$SCRIPT_DIR/Makefile" ]; then
|
|
86
|
+
exec make -C "$SCRIPT_DIR" dev "$@"
|
|
87
|
+
else
|
|
88
|
+
${e.fallbackDevCommand}
|
|
89
|
+
fi
|
|
90
|
+
;;
|
|
91
|
+
start)
|
|
92
|
+
BIN="$SCRIPT_DIR/bin/${e.projectName}"
|
|
93
|
+
if [ ! -f "$BIN" ]; then
|
|
94
|
+
make -C "$SCRIPT_DIR" build
|
|
95
|
+
fi
|
|
96
|
+
exec "$BIN" "$@"
|
|
97
|
+
;;
|
|
98
|
+
build)
|
|
99
|
+
exec make -C "$SCRIPT_DIR" build "$@"
|
|
100
|
+
;;
|
|
101
|
+
test)
|
|
102
|
+
exec make -C "$SCRIPT_DIR" test "$@"
|
|
103
|
+
;;
|
|
104
|
+
lint)
|
|
105
|
+
exec make -C "$SCRIPT_DIR" lint "$@"
|
|
106
|
+
;;
|
|
107
|
+
format|fmt)
|
|
108
|
+
exec make -C "$SCRIPT_DIR" fmt "$@"
|
|
109
|
+
;;
|
|
110
|
+
docs)
|
|
111
|
+
exec make -C "$SCRIPT_DIR" docs "$@"
|
|
112
|
+
;;
|
|
113
|
+
help|--help|-h)
|
|
114
|
+
echo "RapidKit \u2014 ${e.runtimeLabel} project: ${e.projectName}"
|
|
115
|
+
echo ""
|
|
116
|
+
echo "Usage: rapidkit <command>"
|
|
117
|
+
echo ""
|
|
118
|
+
echo " init Install tools + create .env (air, swag, go mod tidy)"
|
|
119
|
+
echo " dev Hot reload dev server (make dev \u2014 requires air)"
|
|
120
|
+
echo " start Run compiled binary (make build + bin)"
|
|
121
|
+
echo " build Build binary (make build)"
|
|
122
|
+
echo " docs Generate Swagger docs (make docs \u2014 requires swag)"
|
|
123
|
+
echo " test Run tests (make test)"
|
|
124
|
+
echo " lint Run linter (make lint)"
|
|
125
|
+
echo " format Format code (make fmt)"
|
|
126
|
+
;;
|
|
127
|
+
*)
|
|
128
|
+
if [ -n "$CMD" ]; then
|
|
129
|
+
echo "rapidkit: unknown command: $CMD" >&2
|
|
130
|
+
fi
|
|
131
|
+
echo "Available: init, dev, start, build, docs, test, lint, format" >&2
|
|
132
|
+
exit 1
|
|
133
|
+
;;
|
|
134
|
+
esac
|
|
135
|
+
`}function v(e){return `@echo off
|
|
136
|
+
rem RapidKit ${e.runtimeLabel} project launcher \u2014 Windows
|
|
137
|
+
set CMD=%1
|
|
138
|
+
if "%CMD%"=="" goto usage
|
|
139
|
+
shift
|
|
140
|
+
|
|
141
|
+
if "%CMD%"=="init" (
|
|
142
|
+
echo Initializing ${e.runtimeLabel} project...
|
|
143
|
+
go install ${i}
|
|
144
|
+
go install ${a}
|
|
145
|
+
if not exist .env if exist .env.example copy .env.example .env
|
|
146
|
+
go mod tidy
|
|
147
|
+
exit /b %ERRORLEVEL%
|
|
148
|
+
)
|
|
149
|
+
if "%CMD%"=="dev" ( make dev %* & exit /b %ERRORLEVEL% )
|
|
150
|
+
if "%CMD%"=="build" ( make build %* & exit /b %ERRORLEVEL% )
|
|
151
|
+
if "%CMD%"=="test" ( make test %* & exit /b %ERRORLEVEL% )
|
|
152
|
+
if "%CMD%"=="lint" ( make lint %* & exit /b %ERRORLEVEL% )
|
|
153
|
+
if "%CMD%"=="format" ( make fmt %* & exit /b %ERRORLEVEL% )
|
|
154
|
+
if "%CMD%"=="docs" ( make docs %* & exit /b %ERRORLEVEL% )
|
|
155
|
+
if "%CMD%"=="start" ( bin\\${e.projectName}.exe %* & exit /b %ERRORLEVEL% )
|
|
156
|
+
|
|
157
|
+
:usage
|
|
158
|
+
echo Available: init, dev, start, build, docs, test, lint, format
|
|
159
|
+
exit /b 1
|
|
160
|
+
`}export{g as a,u as b,$ as c,h as d,p as e,v as f};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {b as b$1}from'./chunk-Q7ULIFQA.js';import {promises}from'fs';import
|
|
1
|
+
import {c,b as b$1,d as d$1,e,f,a}from'./chunk-U7XJZHU6.js';import {b}from'./chunk-Q7ULIFQA.js';import {promises}from'fs';import d from'path';import o from'chalk';import S from'ora';import {execa}from'execa';function _(e){return `package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"fmt"
|
|
@@ -52,7 +52,7 @@ func main() {
|
|
|
52
52
|
}
|
|
53
53
|
slog.Info("server stopped")
|
|
54
54
|
}
|
|
55
|
-
`}function
|
|
55
|
+
`}function T(e){return `module ${e.module_path}
|
|
56
56
|
|
|
57
57
|
go ${e.go_version}
|
|
58
58
|
|
|
@@ -61,32 +61,7 @@ require (
|
|
|
61
61
|
github.com/swaggo/fiber-swagger v1.3.0
|
|
62
62
|
github.com/swaggo/swag v1.16.3
|
|
63
63
|
)
|
|
64
|
-
|
|
65
|
-
require (
|
|
66
|
-
github.com/KyleBanks/depth v1.2.1 // indirect
|
|
67
|
-
github.com/andybalholm/brotli v1.1.0 // indirect
|
|
68
|
-
github.com/ghodss/yaml v1.0.0 // indirect
|
|
69
|
-
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
|
70
|
-
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
|
71
|
-
github.com/go-openapi/spec v0.21.0 // indirect
|
|
72
|
-
github.com/go-openapi/swag v0.23.0 // indirect
|
|
73
|
-
github.com/josharian/intern v1.0.0 // indirect
|
|
74
|
-
github.com/klauspost/compress v1.17.6 // indirect
|
|
75
|
-
github.com/mailru/easyjson v0.7.7 // indirect
|
|
76
|
-
github.com/mattn/go-colorable v0.1.13 // indirect
|
|
77
|
-
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
78
|
-
github.com/mattn/go-runewidth v0.0.15 // indirect
|
|
79
|
-
github.com/rivo/uniseg v0.2.0 // indirect
|
|
80
|
-
github.com/swaggo/files v1.0.1 // indirect
|
|
81
|
-
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
|
82
|
-
github.com/valyala/fasthttp v1.52.0 // indirect
|
|
83
|
-
github.com/valyala/tcplisten v1.0.0 // indirect
|
|
84
|
-
golang.org/x/net v0.25.0 // indirect
|
|
85
|
-
golang.org/x/sys v0.16.0 // indirect
|
|
86
|
-
golang.org/x/tools v0.21.0 // indirect
|
|
87
|
-
gopkg.in/yaml.v2 v2.4.0 // indirect
|
|
88
|
-
)
|
|
89
|
-
`}function w(e){return `package config
|
|
64
|
+
`}function q(e){return `package config
|
|
90
65
|
|
|
91
66
|
import (
|
|
92
67
|
"log/slog"
|
|
@@ -139,7 +114,7 @@ func getEnv(key, fallback string) string {
|
|
|
139
114
|
}
|
|
140
115
|
return fallback
|
|
141
116
|
}
|
|
142
|
-
`}function
|
|
117
|
+
`}function O(e){return `package server
|
|
143
118
|
|
|
144
119
|
import (
|
|
145
120
|
"net/http"
|
|
@@ -205,7 +180,7 @@ func NewApp(cfg *config.Config) *fiber.App {
|
|
|
205
180
|
|
|
206
181
|
return app
|
|
207
182
|
}
|
|
208
|
-
`}function
|
|
183
|
+
`}function y(){return `package handlers
|
|
209
184
|
|
|
210
185
|
import (
|
|
211
186
|
"time"
|
|
@@ -243,7 +218,7 @@ func Readiness(c *fiber.Ctx) error {
|
|
|
243
218
|
"time": time.Now().UTC().Format(time.RFC3339),
|
|
244
219
|
})
|
|
245
220
|
}
|
|
246
|
-
`}function
|
|
221
|
+
`}function C(e){return `package handlers_test
|
|
247
222
|
|
|
248
223
|
import (
|
|
249
224
|
"encoding/json"
|
|
@@ -292,7 +267,7 @@ func TestReadiness(t *testing.T) {
|
|
|
292
267
|
t.Fatalf("expected 200, got %d: %s", resp.StatusCode, resp.Status)
|
|
293
268
|
}
|
|
294
269
|
}
|
|
295
|
-
`}function
|
|
270
|
+
`}function N(){return `# \u2500\u2500 Build stage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
296
271
|
FROM golang:1.24-alpine AS builder
|
|
297
272
|
|
|
298
273
|
# Build-time version injection
|
|
@@ -321,7 +296,7 @@ EXPOSE 3000
|
|
|
321
296
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
322
297
|
CMD wget -qO- http://localhost:3000/api/v1/health/live || exit 1
|
|
323
298
|
ENTRYPOINT ["/server"]
|
|
324
|
-
`}function
|
|
299
|
+
`}function E(e){return `version: "3.9"
|
|
325
300
|
|
|
326
301
|
services:
|
|
327
302
|
api:
|
|
@@ -336,53 +311,7 @@ services:
|
|
|
336
311
|
CORS_ALLOW_ORIGINS: "*"
|
|
337
312
|
RATE_LIMIT_RPS: "100"
|
|
338
313
|
restart: unless-stopped
|
|
339
|
-
`}function
|
|
340
|
-
|
|
341
|
-
# Build-time metadata
|
|
342
|
-
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
|
343
|
-
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "none")
|
|
344
|
-
DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
345
|
-
LDFLAGS = -ldflags "-s -w -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.date=$(DATE)"
|
|
346
|
-
# Go tool binaries are installed to GOPATH/bin; include it so \`air\` and \`swag\` are found.
|
|
347
|
-
GOBIN ?= $(shell go env GOPATH)/bin
|
|
348
|
-
|
|
349
|
-
# Hot reload \u2014 installs air on first use
|
|
350
|
-
dev:
|
|
351
|
-
@test -x "$(GOBIN)/air" || go install github.com/air-verse/air@latest
|
|
352
|
-
$(GOBIN)/air
|
|
353
|
-
|
|
354
|
-
run:
|
|
355
|
-
go run $(LDFLAGS) ./cmd/server
|
|
356
|
-
|
|
357
|
-
build:
|
|
358
|
-
go build $(LDFLAGS) -o bin/${e.project_name} ./cmd/server
|
|
359
|
-
|
|
360
|
-
test:
|
|
361
|
-
go test ./... -v -race
|
|
362
|
-
|
|
363
|
-
cover:
|
|
364
|
-
go test ./... -race -coverprofile=coverage.out
|
|
365
|
-
go tool cover -html=coverage.out -o coverage.html
|
|
366
|
-
@echo "Coverage report: coverage.html"
|
|
367
|
-
|
|
368
|
-
# Generate Swagger docs \u2014 installs swag on first use
|
|
369
|
-
docs:
|
|
370
|
-
@test -x "$(GOBIN)/swag" || go install github.com/swaggo/swag/cmd/swag@latest
|
|
371
|
-
$(GOBIN)/swag init -g main.go -d cmd/server,internal/handlers,internal/apierr -o docs --parseDependency
|
|
372
|
-
tidy:
|
|
373
|
-
go mod tidy
|
|
374
|
-
|
|
375
|
-
docker-up:
|
|
376
|
-
go mod tidy
|
|
377
|
-
docker compose up --build \\
|
|
378
|
-
--build-arg VERSION=$(VERSION) \\
|
|
379
|
-
--build-arg COMMIT=$(COMMIT) \\
|
|
380
|
-
--build-arg DATE=$(DATE) \\
|
|
381
|
-
-d
|
|
382
|
-
|
|
383
|
-
docker-down:
|
|
384
|
-
docker compose down
|
|
385
|
-
`}function q(e){return `# Application
|
|
314
|
+
`}function L(e){return d$1({projectName:e.project_name,devCommand:"$(GOBIN)/air",runCommand:"go run $(LDFLAGS) ./cmd/server",testCommand:"go test ./... -v -race"})}function G(e){return `# Application
|
|
386
315
|
PORT=${e.port}
|
|
387
316
|
APP_ENV=development
|
|
388
317
|
LOG_LEVEL=debug
|
|
@@ -392,7 +321,7 @@ CORS_ALLOW_ORIGINS=*
|
|
|
392
321
|
|
|
393
322
|
# Rate limiting \u2014 max requests per IP per second
|
|
394
323
|
RATE_LIMIT_RPS=100
|
|
395
|
-
`}function
|
|
324
|
+
`}function A(){return `# Binaries
|
|
396
325
|
bin/
|
|
397
326
|
*.exe
|
|
398
327
|
*.exe~
|
|
@@ -432,7 +361,7 @@ docs/docs.go
|
|
|
432
361
|
# OS
|
|
433
362
|
.DS_Store
|
|
434
363
|
Thumbs.db
|
|
435
|
-
`}function
|
|
364
|
+
`}function I(e){return `name: CI
|
|
436
365
|
|
|
437
366
|
on:
|
|
438
367
|
push:
|
|
@@ -486,7 +415,7 @@ jobs:
|
|
|
486
415
|
uses: golangci/golangci-lint-action@v6
|
|
487
416
|
with:
|
|
488
417
|
version: latest
|
|
489
|
-
`}function
|
|
418
|
+
`}function F(e){return `# ${b$1(e.project_name)}
|
|
490
419
|
|
|
491
420
|
> ${e.description}
|
|
492
421
|
|
|
@@ -601,7 +530,7 @@ ${e.project_name}/
|
|
|
601
530
|
## License
|
|
602
531
|
|
|
603
532
|
${e.app_version} \xB7 ${e.author}
|
|
604
|
-
`}function
|
|
533
|
+
`}function x(){return `package middleware
|
|
605
534
|
|
|
606
535
|
import (
|
|
607
536
|
"crypto/rand"
|
|
@@ -707,7 +636,7 @@ func TestRequestID_IsReused(t *testing.T) {
|
|
|
707
636
|
t.Fatalf("expected X-Request-ID to be reused, got %q", id)
|
|
708
637
|
}
|
|
709
638
|
}
|
|
710
|
-
`}function
|
|
639
|
+
`}function P(){return `// Package apierr provides a consistent JSON error envelope for all API responses.
|
|
711
640
|
//
|
|
712
641
|
// Every error response looks like:
|
|
713
642
|
//
|
|
@@ -771,7 +700,7 @@ func InternalError(c *fiber.Ctx, _ error) error {
|
|
|
771
700
|
func TooManyRequests(c *fiber.Ctx, msg string) error {
|
|
772
701
|
return reply(c, http.StatusTooManyRequests, msg, "TOO_MANY_REQUESTS")
|
|
773
702
|
}
|
|
774
|
-
`}function
|
|
703
|
+
`}function D(e){return `package apierr_test
|
|
775
704
|
|
|
776
705
|
import (
|
|
777
706
|
"encoding/json"
|
|
@@ -903,11 +832,11 @@ func TestTooManyRequests(t *testing.T) {
|
|
|
903
832
|
t.Fatalf("expected TOO_MANY_REQUESTS, got %q", body.Code)
|
|
904
833
|
}
|
|
905
834
|
}
|
|
906
|
-
`}function
|
|
835
|
+
`}function M(e){return `// Package docs provides the swaggo-generated OpenAPI specification.
|
|
907
836
|
//
|
|
908
837
|
// Run \`make docs\` to regenerate after changing handler annotations.
|
|
909
838
|
//
|
|
910
|
-
// @title ${
|
|
839
|
+
// @title ${b$1(e.project_name)} API
|
|
911
840
|
// @version ${e.app_version}
|
|
912
841
|
// @description ${e.description}
|
|
913
842
|
// @host localhost:${e.port}
|
|
@@ -917,7 +846,7 @@ func TestTooManyRequests(t *testing.T) {
|
|
|
917
846
|
// @contact.name ${e.author}
|
|
918
847
|
// @license.name MIT
|
|
919
848
|
package docs
|
|
920
|
-
`}function
|
|
849
|
+
`}function B(e){return `package handlers
|
|
921
850
|
|
|
922
851
|
import (
|
|
923
852
|
"net/http"
|
|
@@ -959,7 +888,7 @@ func EchoParams(c *fiber.Ctx) error {
|
|
|
959
888
|
RequestID: rid,
|
|
960
889
|
})
|
|
961
890
|
}
|
|
962
|
-
`}function
|
|
891
|
+
`}function $(e){return `package handlers_test
|
|
963
892
|
|
|
964
893
|
import (
|
|
965
894
|
"encoding/json"
|
|
@@ -1027,7 +956,7 @@ func TestEchoParams_EmptyName(t *testing.T) {
|
|
|
1027
956
|
t.Fatalf("expected code=BAD_REQUEST, got %v", body["code"])
|
|
1028
957
|
}
|
|
1029
958
|
}
|
|
1030
|
-
`}function
|
|
959
|
+
`}function j(e){return `package config_test
|
|
1031
960
|
|
|
1032
961
|
import (
|
|
1033
962
|
"log/slog"
|
|
@@ -1095,7 +1024,7 @@ func TestLoad_Defaults(t *testing.T) {
|
|
|
1095
1024
|
t.Errorf("expected default LogLevel=debug (development env), got %q", cfg.LogLevel)
|
|
1096
1025
|
}
|
|
1097
1026
|
}
|
|
1098
|
-
`}function
|
|
1027
|
+
`}function H(){return `package middleware
|
|
1099
1028
|
|
|
1100
1029
|
import (
|
|
1101
1030
|
"os"
|
|
@@ -1123,7 +1052,7 @@ func CORS() fiber.Handler {
|
|
|
1123
1052
|
MaxAge: 600,
|
|
1124
1053
|
})
|
|
1125
1054
|
}
|
|
1126
|
-
`}function
|
|
1055
|
+
`}function U(e){return `package middleware_test
|
|
1127
1056
|
|
|
1128
1057
|
import (
|
|
1129
1058
|
"net/http"
|
|
@@ -1195,7 +1124,7 @@ func TestCORS_Default_Origin(t *testing.T) {
|
|
|
1195
1124
|
t.Fatal("expected CORS header when origins defaulting to *")
|
|
1196
1125
|
}
|
|
1197
1126
|
}
|
|
1198
|
-
`}function
|
|
1127
|
+
`}function V(e){return `package server_test
|
|
1199
1128
|
|
|
1200
1129
|
import (
|
|
1201
1130
|
"encoding/json"
|
|
@@ -1284,7 +1213,7 @@ func TestServer_Docs_Redirect(t *testing.T) {
|
|
|
1284
1213
|
t.Fatalf("expected Location=/docs/index.html, got %q", loc)
|
|
1285
1214
|
}
|
|
1286
1215
|
}
|
|
1287
|
-
`}function
|
|
1216
|
+
`}function J(e){return `package middleware
|
|
1288
1217
|
|
|
1289
1218
|
import (
|
|
1290
1219
|
"os"
|
|
@@ -1317,7 +1246,7 @@ func RateLimit() fiber.Handler {
|
|
|
1317
1246
|
},
|
|
1318
1247
|
})
|
|
1319
1248
|
}
|
|
1320
|
-
`}function
|
|
1249
|
+
`}function W(e){return `package middleware_test
|
|
1321
1250
|
|
|
1322
1251
|
import (
|
|
1323
1252
|
"net/http"
|
|
@@ -1393,7 +1322,7 @@ func TestRateLimit_InvalidRPS(t *testing.T) {
|
|
|
1393
1322
|
t.Fatalf("expected 200 with invalid RPS env, got %d", resp.StatusCode)
|
|
1394
1323
|
}
|
|
1395
1324
|
}
|
|
1396
|
-
`}function
|
|
1325
|
+
`}function K(e){return `# Air \u2014 live reload for Go projects
|
|
1397
1326
|
# https://github.com/air-verse/air
|
|
1398
1327
|
root = "."
|
|
1399
1328
|
tmp_dir = "tmp"
|
|
@@ -1417,7 +1346,7 @@ tmp_dir = "tmp"
|
|
|
1417
1346
|
|
|
1418
1347
|
[log]
|
|
1419
1348
|
time = false
|
|
1420
|
-
`}function
|
|
1349
|
+
`}function X(e){return `run:
|
|
1421
1350
|
timeout: 5m
|
|
1422
1351
|
|
|
1423
1352
|
linters:
|
|
@@ -1463,110 +1392,6 @@ issues:
|
|
|
1463
1392
|
linters:
|
|
1464
1393
|
- errcheck
|
|
1465
1394
|
- wrapcheck
|
|
1466
|
-
`}function
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
1471
|
-
CMD="\${1:-}"
|
|
1472
|
-
shift 2>/dev/null || true
|
|
1473
|
-
|
|
1474
|
-
case "$CMD" in
|
|
1475
|
-
init)
|
|
1476
|
-
cd "$SCRIPT_DIR"
|
|
1477
|
-
echo "\u{1F439} Initializing Go/Fiber project\u2026"
|
|
1478
|
-
GOBIN="$(go env GOPATH)/bin"
|
|
1479
|
-
echo " \u2192 installing air (hot reload)\u2026"
|
|
1480
|
-
go install github.com/air-verse/air@latest 2>/dev/null && echo " \u2713 air" || echo " \u26A0 air install failed (run: go install github.com/air-verse/air@latest)"
|
|
1481
|
-
echo " \u2192 installing swag (swagger)\u2026"
|
|
1482
|
-
go install github.com/swaggo/swag/cmd/swag@latest 2>/dev/null && echo " \u2713 swag" || echo " \u26A0 swag install failed (run: go install github.com/swaggo/swag/cmd/swag@latest)"
|
|
1483
|
-
if [ ! -f ".env" ] && [ -f ".env.example" ]; then
|
|
1484
|
-
cp .env.example .env && echo " \u2713 .env created from .env.example"
|
|
1485
|
-
fi
|
|
1486
|
-
go mod tidy && echo " \u2713 go mod tidy"
|
|
1487
|
-
echo " \u2192 generating swagger docs (first build)\u2026"
|
|
1488
|
-
"$(go env GOPATH)/bin/swag" init -g main.go -d cmd/server,internal/handlers,internal/apierr -o docs --parseDependency 2>/dev/null && echo " \u2713 swagger docs generated" || echo " \u26A0 swagger docs skipped (run: rapidkit docs)"
|
|
1489
|
-
echo "\u2705 Ready \u2014 run: rapidkit dev"
|
|
1490
|
-
;;
|
|
1491
|
-
dev)
|
|
1492
|
-
cd "$SCRIPT_DIR"
|
|
1493
|
-
echo "\u{1F4D6} Syncing swagger docs\u2026"
|
|
1494
|
-
"$(go env GOPATH)/bin/swag" init -g main.go -d cmd/server,internal/handlers,internal/apierr -o docs --parseDependency 2>/dev/null || true
|
|
1495
|
-
if [ -f "$SCRIPT_DIR/Makefile" ]; then
|
|
1496
|
-
exec make -C "$SCRIPT_DIR" dev "$@"
|
|
1497
|
-
else
|
|
1498
|
-
exec go run ./cmd/server "$@"
|
|
1499
|
-
fi
|
|
1500
|
-
;;
|
|
1501
|
-
start)
|
|
1502
|
-
BIN="$SCRIPT_DIR/bin/${e.project_name}"
|
|
1503
|
-
if [ ! -f "$BIN" ]; then
|
|
1504
|
-
make -C "$SCRIPT_DIR" build
|
|
1505
|
-
fi
|
|
1506
|
-
exec "$BIN" "$@"
|
|
1507
|
-
;;
|
|
1508
|
-
build)
|
|
1509
|
-
exec make -C "$SCRIPT_DIR" build "$@"
|
|
1510
|
-
;;
|
|
1511
|
-
test)
|
|
1512
|
-
exec make -C "$SCRIPT_DIR" test "$@"
|
|
1513
|
-
;;
|
|
1514
|
-
lint)
|
|
1515
|
-
exec make -C "$SCRIPT_DIR" lint "$@"
|
|
1516
|
-
;;
|
|
1517
|
-
format|fmt)
|
|
1518
|
-
exec make -C "$SCRIPT_DIR" fmt "$@"
|
|
1519
|
-
;;
|
|
1520
|
-
docs)
|
|
1521
|
-
exec make -C "$SCRIPT_DIR" docs "$@"
|
|
1522
|
-
;;
|
|
1523
|
-
help|--help|-h)
|
|
1524
|
-
echo "RapidKit \u2014 Go/Fiber project: ${e.project_name}"
|
|
1525
|
-
echo ""
|
|
1526
|
-
echo "Usage: rapidkit <command>"
|
|
1527
|
-
echo ""
|
|
1528
|
-
echo " init Install tools + create .env (air, swag, go mod tidy)"
|
|
1529
|
-
echo " dev Hot reload dev server (make dev \u2014 requires air)"
|
|
1530
|
-
echo " start Run compiled binary (make build + bin)"
|
|
1531
|
-
echo " build Build binary (make build)"
|
|
1532
|
-
echo " docs Generate Swagger docs (make docs \u2014 requires swag)"
|
|
1533
|
-
echo " test Run tests (make test)"
|
|
1534
|
-
echo " lint Run linter (make lint)"
|
|
1535
|
-
echo " format Format code (make fmt)"
|
|
1536
|
-
;;
|
|
1537
|
-
*)
|
|
1538
|
-
if [ -n "$CMD" ]; then
|
|
1539
|
-
echo "rapidkit: unknown command: $CMD" >&2
|
|
1540
|
-
fi
|
|
1541
|
-
echo "Available: init, dev, start, build, docs, test, lint, format" >&2
|
|
1542
|
-
exit 1
|
|
1543
|
-
;;
|
|
1544
|
-
esac
|
|
1545
|
-
`}function K(e){return `@echo off
|
|
1546
|
-
rem RapidKit Go/Fiber project launcher \u2014 Windows
|
|
1547
|
-
set CMD=%1
|
|
1548
|
-
if "%CMD%"=="" goto usage
|
|
1549
|
-
shift
|
|
1550
|
-
|
|
1551
|
-
if "%CMD%"=="init" (
|
|
1552
|
-
echo Initializing Go/Fiber project...
|
|
1553
|
-
go install github.com/air-verse/air@latest
|
|
1554
|
-
go install github.com/swaggo/swag/cmd/swag@latest
|
|
1555
|
-
if not exist .env if exist .env.example copy .env.example .env
|
|
1556
|
-
go mod tidy
|
|
1557
|
-
exit /b %ERRORLEVEL%
|
|
1558
|
-
)
|
|
1559
|
-
if "%CMD%"=="dev" ( make dev %* & exit /b %ERRORLEVEL% )
|
|
1560
|
-
if "%CMD%"=="build" ( make build %* & exit /b %ERRORLEVEL% )
|
|
1561
|
-
if "%CMD%"=="test" ( make test %* & exit /b %ERRORLEVEL% )
|
|
1562
|
-
if "%CMD%"=="lint" ( make lint %* & exit /b %ERRORLEVEL% )
|
|
1563
|
-
if "%CMD%"=="format" ( make fmt %* & exit /b %ERRORLEVEL% )
|
|
1564
|
-
if "%CMD%"=="docs" ( make docs %* & exit /b %ERRORLEVEL% )
|
|
1565
|
-
if "%CMD%"=="start" ( bin\\${e.project_name}.exe %* & exit /b %ERRORLEVEL% )
|
|
1566
|
-
|
|
1567
|
-
:usage
|
|
1568
|
-
echo Available: init, dev, start, build, docs, test, lint, format
|
|
1569
|
-
exit /b 1
|
|
1570
|
-
`}function X(e,o){return JSON.stringify({kit_name:"gofiber.standard",runtime:"go",module_support:false,project_name:e.project_name,module_path:e.module_path,app_version:e.app_version,created_by:"rapidkit-npm",rapidkit_version:o,created_at:new Date().toISOString()},null,2)}async function ie(e,o){let r={project_name:o.project_name,module_path:o.module_path||o.project_name,author:o.author||"RapidKit User",description:o.description||`Go/Fiber REST API \u2014 ${o.project_name}`,go_version:o.go_version||"1.24",app_version:o.app_version||"0.1.0",port:o.port||"3000",skipGit:o.skipGit??false},p=b$1();try{await execa("go",["version"],{timeout:3e3});}catch{console.log(i.yellow("\n\u26A0 Go not found in PATH \u2014 project will be scaffolded, but `go mod tidy` requires Go 1.21+")),console.log(i.gray(` Install: https://go.dev/dl/
|
|
1571
|
-
`));}let a=h(`Generating Go/Fiber project: ${r.project_name}\u2026`).start();try{let t=(f,m)=>b(s.join(e,f),m),u=s.join(e,"rapidkit"),g=s.join(e,"rapidkit.cmd");await Promise.all([t("cmd/server/main.go",v(r)),t("go.mod",R(r)),t("internal/config/config.go",w(r)),t("internal/server/server.go",S(r)),t("internal/middleware/requestid.go",I()),t("internal/middleware/requestid_test.go",k(r)),t("internal/apierr/apierr.go",A()),t("internal/apierr/apierr_test.go",G(r)),t("internal/handlers/health.go",_()),t("internal/handlers/health_test.go",T(r)),t("internal/handlers/example.go",F(r)),t("internal/handlers/example_test.go",D(r)),t("internal/config/config_test.go",P(r)),t("internal/middleware/cors.go",M()),t("internal/middleware/cors_test.go",$(r)),t("internal/middleware/ratelimit.go",j(r)),t("internal/middleware/ratelimit_test.go",H(r)),t("internal/server/server_test.go",B(r)),t("docs/doc.go",x(r)),t(".air.toml",U(r)),t("Dockerfile",y()),t("docker-compose.yml",O(r)),t("Makefile",C(r)),t(".golangci.yml",V(r.module_path)),t(".env.example",q(r)),t(".gitignore",E()),t(".github/workflows/ci.yml",N(r)),t("README.md",L(r)),t(".rapidkit/project.json",X(r,p)),t(".rapidkit/context.json",J()),t("rapidkit",W(r)),t("rapidkit.cmd",K(r))]),await promises.chmod(u,493),await promises.chmod(g,493),a.succeed(i.green(`Project created at ${e}`));try{a.start("Fetching Go dependencies\u2026"),await execa("go",["mod","tidy"],{cwd:e,timeout:12e4}),a.succeed(i.gray("\u2713 go mod tidy completed"));}catch{a.warn(i.yellow("\u26A0 go mod tidy failed \u2014 run manually: go mod tidy"));}if(!r.skipGit)try{await execa("git",["init"],{cwd:e}),await execa("git",["add","-A"],{cwd:e}),await execa("git",["commit","-m","chore: initial scaffold (rapidkit gofiber.standard)"],{cwd:e}),console.log(i.gray("\u2713 git repository initialized"));}catch{console.log(i.gray("\u26A0 git init skipped (git not found or error)"));}console.log(""),console.log(i.bold("\u2705 Go/Fiber project ready!")),console.log(""),console.log(i.cyan("Next steps:")),console.log(i.white(` cd ${r.project_name}`)),console.log(i.white(" make run # start dev server")),console.log(i.white(" make test # run tests")),console.log(""),console.log(i.gray("Server will listen on port "+r.port)),console.log(i.gray(" http://localhost:"+r.port+"/api/v1/health/live")),console.log(i.gray(" http://localhost:"+r.port+"/api/v1/health/ready")),console.log(""),console.log(i.yellow("\u2139 RapidKit modules are not available for Go projects (module system uses Python/pip).")),console.log("");}catch(t){throw a.fail(i.red("Failed to generate Go/Fiber project")),t}}
|
|
1572
|
-
export{ie as generateGoFiberKit};
|
|
1395
|
+
`}function Q(){return JSON.stringify({engine:"npm",runtime:"go"},null,2)}function Y(e$1){return e({runtimeLabel:"Go/Fiber",projectName:e$1.project_name,fallbackDevCommand:'exec go run ./cmd/server "$@"'})}function z(e){return f({runtimeLabel:"Go/Fiber",projectName:e.project_name})}function Z(e,i){return JSON.stringify({kit_name:"gofiber.standard",runtime:"go",module_support:false,project_name:e.project_name,module_path:e.module_path,app_version:e.app_version,created_by:"rapidkit-npm",rapidkit_version:i,created_at:new Date().toISOString()},null,2)}async function pe(e,i){let r={project_name:i.project_name,module_path:i.module_path||i.project_name,author:i.author||"RapidKit User",description:i.description||`Go/Fiber REST API \u2014 ${i.project_name}`,go_version:i.go_version||a,app_version:i.app_version||"0.1.0",port:i.port||"3000",skipGit:i.skipGit??false},h=b();try{await execa("go",["version"],{timeout:3e3});}catch{console.log(o.yellow("\n\u26A0 Go not found in PATH \u2014 project will be scaffolded, but `go mod tidy` requires Go 1.21+")),console.log(o.gray(` Install: https://go.dev/dl/
|
|
1396
|
+
`));}let n=S(`Generating Go/Fiber project: ${r.project_name}\u2026`).start();try{let t=(R,w)=>c(d.join(e,R),w),b=d.join(e,"rapidkit"),v=d.join(e,"rapidkit.cmd");await Promise.all([t("cmd/server/main.go",_(r)),t("go.mod",T(r)),t("internal/config/config.go",q(r)),t("internal/server/server.go",O(r)),t("internal/middleware/requestid.go",x()),t("internal/middleware/requestid_test.go",k(r)),t("internal/apierr/apierr.go",P()),t("internal/apierr/apierr_test.go",D(r)),t("internal/handlers/health.go",y()),t("internal/handlers/health_test.go",C(r)),t("internal/handlers/example.go",B(r)),t("internal/handlers/example_test.go",$(r)),t("internal/config/config_test.go",j(r)),t("internal/middleware/cors.go",H()),t("internal/middleware/cors_test.go",U(r)),t("internal/middleware/ratelimit.go",J(r)),t("internal/middleware/ratelimit_test.go",W(r)),t("internal/server/server_test.go",V(r)),t("docs/doc.go",M(r)),t(".air.toml",K(r)),t("Dockerfile",N()),t("docker-compose.yml",E(r)),t("Makefile",L(r)),t(".golangci.yml",X(r.module_path)),t(".env.example",G(r)),t(".gitignore",A()),t(".github/workflows/ci.yml",I(r)),t("README.md",F(r)),t(".rapidkit/project.json",Z(r,h)),t(".rapidkit/context.json",Q()),t("rapidkit",Y(r)),t("rapidkit.cmd",z(r))]),await promises.chmod(b,493),await promises.chmod(v,493),n.succeed(o.green(`Project created at ${e}`));try{n.start("Fetching Go dependencies\u2026"),await execa("go",["mod","tidy"],{cwd:e,timeout:12e4}),n.succeed(o.gray("\u2713 go mod tidy completed"));}catch{n.warn(o.yellow("\u26A0 go mod tidy failed \u2014 run manually: go mod tidy"));}if(!r.skipGit)try{await execa("git",["init"],{cwd:e}),await execa("git",["add","-A"],{cwd:e}),await execa("git",["commit","-m","chore: initial scaffold (rapidkit gofiber.standard)"],{cwd:e}),console.log(o.gray("\u2713 git repository initialized"));}catch{console.log(o.gray("\u26A0 git init skipped (git not found or error)"));}console.log(""),console.log(o.bold("\u2705 Go/Fiber project ready!")),console.log(""),console.log(o.cyan("Next steps:")),console.log(o.white(` cd ${r.project_name}`)),console.log(o.white(" make run # start dev server")),console.log(o.white(" make test # run tests")),console.log(""),console.log(o.gray("Server will listen on port "+r.port)),console.log(o.gray(" http://localhost:"+r.port+"/api/v1/health/live")),console.log(o.gray(" http://localhost:"+r.port+"/api/v1/health/ready")),console.log(""),console.log(o.yellow("\u2139 RapidKit modules are not available for Go projects (module system uses Python/pip).")),console.log("");}catch(t){throw n.fail(o.red("Failed to generate Go/Fiber project")),t}}
|
|
1397
|
+
export{pe as generateGoFiberKit};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {b as b$1}from'./chunk-Q7ULIFQA.js';import {promises}from'fs';import
|
|
1
|
+
import {c,b as b$2,d as d$1,e,f,a}from'./chunk-U7XJZHU6.js';import {b as b$1}from'./chunk-Q7ULIFQA.js';import {promises}from'fs';import d from'path';import o from'chalk';import _ from'ora';import {execa}from'execa';function T(e){return `package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
@@ -65,56 +65,17 @@ func main() {
|
|
|
65
65
|
}
|
|
66
66
|
slog.Info("server stopped")
|
|
67
67
|
}
|
|
68
|
-
`}function
|
|
68
|
+
`}function O(e){return `module ${e.module_path}
|
|
69
69
|
|
|
70
70
|
go ${e.go_version}
|
|
71
71
|
|
|
72
72
|
require (
|
|
73
73
|
github.com/gin-gonic/gin v1.10.0
|
|
74
|
+
github.com/swaggo/files v1.0.1
|
|
74
75
|
github.com/swaggo/gin-swagger v1.6.0
|
|
75
76
|
github.com/swaggo/swag v1.16.3
|
|
76
77
|
)
|
|
77
|
-
|
|
78
|
-
require (
|
|
79
|
-
github.com/KyleBanks/depth v1.2.1 // indirect
|
|
80
|
-
github.com/bytedance/sonic v1.11.6 // indirect
|
|
81
|
-
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
|
82
|
-
github.com/cloudwego/base64x v0.1.4 // indirect
|
|
83
|
-
github.com/cloudwego/iasm v0.2.0 // indirect
|
|
84
|
-
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
|
85
|
-
github.com/ghodss/yaml v1.0.0 // indirect
|
|
86
|
-
github.com/gin-contrib/sse v0.1.0 // indirect
|
|
87
|
-
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
|
88
|
-
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
|
89
|
-
github.com/go-openapi/spec v0.21.0 // indirect
|
|
90
|
-
github.com/go-openapi/swag v0.23.0 // indirect
|
|
91
|
-
github.com/go-playground/locales v0.14.1 // indirect
|
|
92
|
-
github.com/go-playground/universal-translator v0.18.1 // indirect
|
|
93
|
-
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
|
94
|
-
github.com/goccy/go-json v0.10.2 // indirect
|
|
95
|
-
github.com/josharian/intern v1.0.0 // indirect
|
|
96
|
-
github.com/json-iterator/go v1.1.12 // indirect
|
|
97
|
-
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
|
98
|
-
github.com/leodido/go-urn v1.4.0 // indirect
|
|
99
|
-
github.com/mailru/easyjson v0.7.7 // indirect
|
|
100
|
-
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
101
|
-
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
|
102
|
-
github.com/modern-go/reflect2 v1.0.2 // indirect
|
|
103
|
-
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
|
104
|
-
github.com/swaggo/files v1.0.1 // indirect
|
|
105
|
-
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
|
106
|
-
github.com/ugorji/go/codec v1.2.12 // indirect
|
|
107
|
-
golang.org/x/arch v0.8.0 // indirect
|
|
108
|
-
golang.org/x/crypto v0.23.0 // indirect
|
|
109
|
-
golang.org/x/net v0.25.0 // indirect
|
|
110
|
-
golang.org/x/sys v0.20.0 // indirect
|
|
111
|
-
golang.org/x/text v0.15.0 // indirect
|
|
112
|
-
golang.org/x/tools v0.21.0 // indirect
|
|
113
|
-
google.golang.org/protobuf v1.34.1 // indirect
|
|
114
|
-
gopkg.in/yaml.v2 v2.4.0 // indirect
|
|
115
|
-
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
116
|
-
)
|
|
117
|
-
`}function S(e){return `package config
|
|
78
|
+
`}function N(e){return `package config
|
|
118
79
|
|
|
119
80
|
import (
|
|
120
81
|
"log/slog"
|
|
@@ -221,7 +182,7 @@ func NewRouter(cfg *config.Config) *gin.Engine {
|
|
|
221
182
|
|
|
222
183
|
return r
|
|
223
184
|
}
|
|
224
|
-
`}function
|
|
185
|
+
`}function G(){return `package handlers
|
|
225
186
|
|
|
226
187
|
import (
|
|
227
188
|
"net/http"
|
|
@@ -260,7 +221,7 @@ func Readiness(c *gin.Context) {
|
|
|
260
221
|
"time": time.Now().UTC().Format(time.RFC3339),
|
|
261
222
|
})
|
|
262
223
|
}
|
|
263
|
-
`}function
|
|
224
|
+
`}function q(e){return `package handlers_test
|
|
264
225
|
|
|
265
226
|
import (
|
|
266
227
|
"encoding/json"
|
|
@@ -305,7 +266,7 @@ func TestReadiness(t *testing.T) {
|
|
|
305
266
|
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
|
306
267
|
}
|
|
307
268
|
}
|
|
308
|
-
`}function
|
|
269
|
+
`}function E(){return `# \u2500\u2500 Build stage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
309
270
|
FROM golang:1.24-alpine AS builder
|
|
310
271
|
|
|
311
272
|
# Build-time version injection
|
|
@@ -334,7 +295,7 @@ EXPOSE 8080
|
|
|
334
295
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
335
296
|
CMD wget -qO- http://localhost:8080/api/v1/health/live || exit 1
|
|
336
297
|
ENTRYPOINT ["/server"]
|
|
337
|
-
`}function
|
|
298
|
+
`}function L(e){return `version: "3.9"
|
|
338
299
|
|
|
339
300
|
services:
|
|
340
301
|
api:
|
|
@@ -350,61 +311,7 @@ services:
|
|
|
350
311
|
CORS_ALLOW_ORIGINS: "*"
|
|
351
312
|
RATE_LIMIT_RPS: "100"
|
|
352
313
|
restart: unless-stopped
|
|
353
|
-
`}function
|
|
354
|
-
|
|
355
|
-
# Build-time metadata
|
|
356
|
-
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
|
357
|
-
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "none")
|
|
358
|
-
DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
359
|
-
LDFLAGS = -ldflags "-s -w -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.date=$(DATE)"
|
|
360
|
-
# Go tool binaries are installed to GOPATH/bin; include it so \`air\` and \`swag\` are found.
|
|
361
|
-
GOBIN ?= $(shell go env GOPATH)/bin
|
|
362
|
-
|
|
363
|
-
# Hot reload \u2014 installs air on first use
|
|
364
|
-
dev:
|
|
365
|
-
@test -x "$(GOBIN)/air" || go install github.com/air-verse/air@latest
|
|
366
|
-
GIN_MODE=debug $(GOBIN)/air
|
|
367
|
-
|
|
368
|
-
run:
|
|
369
|
-
GIN_MODE=debug go run $(LDFLAGS) ./cmd/server
|
|
370
|
-
|
|
371
|
-
build:
|
|
372
|
-
go build $(LDFLAGS) -o bin/${e.project_name} ./cmd/server
|
|
373
|
-
|
|
374
|
-
test:
|
|
375
|
-
GIN_MODE=test go test ./... -v -race
|
|
376
|
-
|
|
377
|
-
cover:
|
|
378
|
-
GIN_MODE=test go test ./... -race -coverprofile=coverage.out
|
|
379
|
-
go tool cover -html=coverage.out -o coverage.html
|
|
380
|
-
@echo "Coverage report: coverage.html"
|
|
381
|
-
|
|
382
|
-
# Generate Swagger docs \u2014 installs swag on first use
|
|
383
|
-
docs:
|
|
384
|
-
@test -x "$(GOBIN)/swag" || go install github.com/swaggo/swag/cmd/swag@latest
|
|
385
|
-
$(GOBIN)/swag init -g main.go -d cmd/server,internal/handlers,internal/apierr -o docs --parseDependency
|
|
386
|
-
|
|
387
|
-
lint:
|
|
388
|
-
@command -v golangci-lint >/dev/null 2>&1 || (echo "golangci-lint not found. Install: https://golangci-lint.run/usage/install/" && exit 1)
|
|
389
|
-
golangci-lint run ./...
|
|
390
|
-
|
|
391
|
-
fmt:
|
|
392
|
-
gofmt -w .
|
|
393
|
-
|
|
394
|
-
tidy:
|
|
395
|
-
go mod tidy
|
|
396
|
-
|
|
397
|
-
docker-up:
|
|
398
|
-
go mod tidy
|
|
399
|
-
docker compose up --build \\
|
|
400
|
-
--build-arg VERSION=$(VERSION) \\
|
|
401
|
-
--build-arg COMMIT=$(COMMIT) \\
|
|
402
|
-
--build-arg DATE=$(DATE) \\
|
|
403
|
-
-d
|
|
404
|
-
|
|
405
|
-
docker-down:
|
|
406
|
-
docker compose down
|
|
407
|
-
`}function G(e){return `# Application
|
|
314
|
+
`}function C(e){return d$1({projectName:e.project_name,devCommand:"GIN_MODE=debug $(GOBIN)/air",runCommand:"GIN_MODE=debug go run $(LDFLAGS) ./cmd/server",testCommand:"GIN_MODE=test go test ./... -v -race",includeLintAndFmt:true})}function y(e){return `# Application
|
|
408
315
|
PORT=${e.port}
|
|
409
316
|
APP_ENV=development
|
|
410
317
|
GIN_MODE=debug
|
|
@@ -415,7 +322,7 @@ CORS_ALLOW_ORIGINS=*
|
|
|
415
322
|
|
|
416
323
|
# Rate limiting \u2014 max requests per IP per second
|
|
417
324
|
RATE_LIMIT_RPS=100
|
|
418
|
-
`}function
|
|
325
|
+
`}function I(){return `# Binaries
|
|
419
326
|
bin/
|
|
420
327
|
*.exe
|
|
421
328
|
*.exe~
|
|
@@ -455,7 +362,7 @@ docs/docs.go
|
|
|
455
362
|
# OS
|
|
456
363
|
.DS_Store
|
|
457
364
|
Thumbs.db
|
|
458
|
-
`}function
|
|
365
|
+
`}function x(e){return `name: CI
|
|
459
366
|
|
|
460
367
|
on:
|
|
461
368
|
push:
|
|
@@ -509,7 +416,7 @@ jobs:
|
|
|
509
416
|
uses: golangci/golangci-lint-action@v6
|
|
510
417
|
with:
|
|
511
418
|
version: latest
|
|
512
|
-
`}function
|
|
419
|
+
`}function M(e){return `# ${b$2(e.project_name)}
|
|
513
420
|
|
|
514
421
|
> ${e.description}
|
|
515
422
|
|
|
@@ -625,7 +532,7 @@ ${e.project_name}/
|
|
|
625
532
|
## License
|
|
626
533
|
|
|
627
534
|
${e.app_version} \xB7 ${e.author}
|
|
628
|
-
`}function
|
|
535
|
+
`}function k(){return `package middleware
|
|
629
536
|
|
|
630
537
|
import (
|
|
631
538
|
"crypto/rand"
|
|
@@ -677,7 +584,7 @@ func newID() string {
|
|
|
677
584
|
}
|
|
678
585
|
return hex.EncodeToString(b)
|
|
679
586
|
}
|
|
680
|
-
`}function
|
|
587
|
+
`}function A(e){return `package middleware_test
|
|
681
588
|
|
|
682
589
|
import (
|
|
683
590
|
"net/http"
|
|
@@ -726,7 +633,7 @@ func TestRequestID_IsReused(t *testing.T) {
|
|
|
726
633
|
t.Fatalf("expected X-Request-ID to be reused, got %q", id)
|
|
727
634
|
}
|
|
728
635
|
}
|
|
729
|
-
`}function
|
|
636
|
+
`}function P(){return `// Package apierr provides a consistent JSON error envelope for all API responses.
|
|
730
637
|
//
|
|
731
638
|
// Every error response looks like:
|
|
732
639
|
//
|
|
@@ -789,7 +696,7 @@ func InternalError(c *gin.Context, _ error) {
|
|
|
789
696
|
func TooManyRequests(c *gin.Context) {
|
|
790
697
|
reply(c, http.StatusTooManyRequests, "rate limit exceeded", "TOO_MANY_REQUESTS")
|
|
791
698
|
}
|
|
792
|
-
`}function
|
|
699
|
+
`}function D(e){return `package apierr_test
|
|
793
700
|
|
|
794
701
|
import (
|
|
795
702
|
"encoding/json"
|
|
@@ -915,11 +822,11 @@ func TestTooManyRequests(t *testing.T) {
|
|
|
915
822
|
t.Fatalf("expected TOO_MANY_REQUESTS, got %q", body.Code)
|
|
916
823
|
}
|
|
917
824
|
}
|
|
918
|
-
`}function
|
|
825
|
+
`}function H(e){return `// Package docs provides the swaggo-generated OpenAPI specification.
|
|
919
826
|
//
|
|
920
827
|
// Run \`make docs\` to regenerate after changing handler annotations.
|
|
921
828
|
//
|
|
922
|
-
// @title ${
|
|
829
|
+
// @title ${b$2(e.project_name)} API
|
|
923
830
|
// @version ${e.app_version}
|
|
924
831
|
// @description ${e.description}
|
|
925
832
|
// @host localhost:${e.port}
|
|
@@ -929,7 +836,7 @@ func TestTooManyRequests(t *testing.T) {
|
|
|
929
836
|
// @contact.name ${e.author}
|
|
930
837
|
// @license.name MIT
|
|
931
838
|
package docs
|
|
932
|
-
`}function
|
|
839
|
+
`}function F(e){return `package handlers
|
|
933
840
|
|
|
934
841
|
import (
|
|
935
842
|
"net/http"
|
|
@@ -971,7 +878,7 @@ func EchoParams(c *gin.Context) {
|
|
|
971
878
|
RequestID: c.GetString("X-Request-ID"),
|
|
972
879
|
})
|
|
973
880
|
}
|
|
974
|
-
`}function
|
|
881
|
+
`}function $(e){return `package handlers_test
|
|
975
882
|
|
|
976
883
|
import (
|
|
977
884
|
"encoding/json"
|
|
@@ -1036,7 +943,7 @@ func TestEchoParams_EmptyName(t *testing.T) {
|
|
|
1036
943
|
t.Fatalf("expected code=BAD_REQUEST, got %v", body["code"])
|
|
1037
944
|
}
|
|
1038
945
|
}
|
|
1039
|
-
`}function
|
|
946
|
+
`}function j(e){return `package config_test
|
|
1040
947
|
|
|
1041
948
|
import (
|
|
1042
949
|
"log/slog"
|
|
@@ -1112,7 +1019,7 @@ func TestLoad_Defaults(t *testing.T) {
|
|
|
1112
1019
|
t.Errorf("expected default GinMode=debug, got %q", cfg.GinMode)
|
|
1113
1020
|
}
|
|
1114
1021
|
}
|
|
1115
|
-
`}function
|
|
1022
|
+
`}function U(){return `package middleware
|
|
1116
1023
|
|
|
1117
1024
|
import (
|
|
1118
1025
|
"net/http"
|
|
@@ -1160,7 +1067,7 @@ func CORS() gin.HandlerFunc {
|
|
|
1160
1067
|
c.Next()
|
|
1161
1068
|
}
|
|
1162
1069
|
}
|
|
1163
|
-
`}function
|
|
1070
|
+
`}function B(e){return `package middleware_test
|
|
1164
1071
|
|
|
1165
1072
|
import (
|
|
1166
1073
|
"net/http"
|
|
@@ -1246,7 +1153,7 @@ func TestCORS_Default_Origin(t *testing.T) {
|
|
|
1246
1153
|
t.Fatal("expected CORS header when CORS_ALLOW_ORIGINS defaults to *")
|
|
1247
1154
|
}
|
|
1248
1155
|
}
|
|
1249
|
-
`}function
|
|
1156
|
+
`}function V(e){return `package server_test
|
|
1250
1157
|
|
|
1251
1158
|
import (
|
|
1252
1159
|
"encoding/json"
|
|
@@ -1356,7 +1263,7 @@ func TestServer_ReleaseMode(t *testing.T) {
|
|
|
1356
1263
|
t.Fatalf("expected 200 in release mode, got %d", w.Code)
|
|
1357
1264
|
}
|
|
1358
1265
|
}
|
|
1359
|
-
`}function
|
|
1266
|
+
`}function W(e){return `package middleware
|
|
1360
1267
|
|
|
1361
1268
|
import (
|
|
1362
1269
|
"os"
|
|
@@ -1407,7 +1314,7 @@ func RateLimit() gin.HandlerFunc {
|
|
|
1407
1314
|
c.Next()
|
|
1408
1315
|
}
|
|
1409
1316
|
}
|
|
1410
|
-
`}function
|
|
1317
|
+
`}function J(e){return `package middleware_test
|
|
1411
1318
|
|
|
1412
1319
|
import (
|
|
1413
1320
|
"net/http"
|
|
@@ -1476,7 +1383,7 @@ func TestRateLimit_InvalidRPS(t *testing.T) {
|
|
|
1476
1383
|
t.Fatalf("expected 200 with invalid RPS env, got %d", w.Code)
|
|
1477
1384
|
}
|
|
1478
1385
|
}
|
|
1479
|
-
`}function
|
|
1386
|
+
`}function K(e){return `# Air \u2014 live reload for Go projects
|
|
1480
1387
|
# https://github.com/air-verse/air
|
|
1481
1388
|
root = "."
|
|
1482
1389
|
tmp_dir = "tmp"
|
|
@@ -1501,7 +1408,7 @@ tmp_dir = "tmp"
|
|
|
1501
1408
|
|
|
1502
1409
|
[log]
|
|
1503
1410
|
time = false
|
|
1504
|
-
`}function
|
|
1411
|
+
`}function X(e){return `run:
|
|
1505
1412
|
timeout: 5m
|
|
1506
1413
|
|
|
1507
1414
|
linters:
|
|
@@ -1547,110 +1454,6 @@ issues:
|
|
|
1547
1454
|
linters:
|
|
1548
1455
|
- errcheck
|
|
1549
1456
|
- wrapcheck
|
|
1550
|
-
`}function
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
1555
|
-
CMD="\${1:-}"
|
|
1556
|
-
shift 2>/dev/null || true
|
|
1557
|
-
|
|
1558
|
-
case "$CMD" in
|
|
1559
|
-
init)
|
|
1560
|
-
cd "$SCRIPT_DIR"
|
|
1561
|
-
echo "\u{1F439} Initializing Go/Gin project\u2026"
|
|
1562
|
-
GOBIN="$(go env GOPATH)/bin"
|
|
1563
|
-
echo " \u2192 installing air (hot reload)\u2026"
|
|
1564
|
-
go install github.com/air-verse/air@latest 2>/dev/null && echo " \u2713 air" || echo " \u26A0 air install failed (run: go install github.com/air-verse/air@latest)"
|
|
1565
|
-
echo " \u2192 installing swag (swagger)\u2026"
|
|
1566
|
-
go install github.com/swaggo/swag/cmd/swag@latest 2>/dev/null && echo " \u2713 swag" || echo " \u26A0 swag install failed (run: go install github.com/swaggo/swag/cmd/swag@latest)"
|
|
1567
|
-
if [ ! -f ".env" ] && [ -f ".env.example" ]; then
|
|
1568
|
-
cp .env.example .env && echo " \u2713 .env created from .env.example"
|
|
1569
|
-
fi
|
|
1570
|
-
go mod tidy && echo " \u2713 go mod tidy"
|
|
1571
|
-
echo " \u2192 generating swagger docs (first build)\u2026"
|
|
1572
|
-
"$(go env GOPATH)/bin/swag" init -g main.go -d cmd/server,internal/handlers,internal/apierr -o docs --parseDependency 2>/dev/null && echo " \u2713 swagger docs generated" || echo " \u26A0 swagger docs skipped (run: rapidkit docs)"
|
|
1573
|
-
echo "\u2705 Ready \u2014 run: rapidkit dev"
|
|
1574
|
-
;;
|
|
1575
|
-
dev)
|
|
1576
|
-
cd "$SCRIPT_DIR"
|
|
1577
|
-
echo "\u{1F4D6} Syncing swagger docs\u2026"
|
|
1578
|
-
"$(go env GOPATH)/bin/swag" init -g main.go -d cmd/server,internal/handlers,internal/apierr -o docs --parseDependency 2>/dev/null || true
|
|
1579
|
-
if [ -f "$SCRIPT_DIR/Makefile" ]; then
|
|
1580
|
-
exec make -C "$SCRIPT_DIR" dev "$@"
|
|
1581
|
-
else
|
|
1582
|
-
cd "$SCRIPT_DIR" && GIN_MODE=debug exec go run ./cmd/server "$@"
|
|
1583
|
-
fi
|
|
1584
|
-
;;
|
|
1585
|
-
start)
|
|
1586
|
-
BIN="$SCRIPT_DIR/bin/${e.project_name}"
|
|
1587
|
-
if [ ! -f "$BIN" ]; then
|
|
1588
|
-
make -C "$SCRIPT_DIR" build
|
|
1589
|
-
fi
|
|
1590
|
-
exec "$BIN" "$@"
|
|
1591
|
-
;;
|
|
1592
|
-
build)
|
|
1593
|
-
exec make -C "$SCRIPT_DIR" build "$@"
|
|
1594
|
-
;;
|
|
1595
|
-
test)
|
|
1596
|
-
exec make -C "$SCRIPT_DIR" test "$@"
|
|
1597
|
-
;;
|
|
1598
|
-
lint)
|
|
1599
|
-
exec make -C "$SCRIPT_DIR" lint "$@"
|
|
1600
|
-
;;
|
|
1601
|
-
format|fmt)
|
|
1602
|
-
exec make -C "$SCRIPT_DIR" fmt "$@"
|
|
1603
|
-
;;
|
|
1604
|
-
docs)
|
|
1605
|
-
exec make -C "$SCRIPT_DIR" docs "$@"
|
|
1606
|
-
;;
|
|
1607
|
-
help|--help|-h)
|
|
1608
|
-
echo "RapidKit \u2014 Go/Gin project: ${e.project_name}"
|
|
1609
|
-
echo ""
|
|
1610
|
-
echo "Usage: rapidkit <command>"
|
|
1611
|
-
echo ""
|
|
1612
|
-
echo " init Install tools + create .env (air, swag, go mod tidy)"
|
|
1613
|
-
echo " dev Hot reload dev server (make dev \u2014 requires air)"
|
|
1614
|
-
echo " start Run compiled binary (make build + bin)"
|
|
1615
|
-
echo " build Build binary (make build)"
|
|
1616
|
-
echo " docs Generate Swagger docs (make docs \u2014 requires swag)"
|
|
1617
|
-
echo " test Run tests (make test)"
|
|
1618
|
-
echo " lint Run linter (make lint)"
|
|
1619
|
-
echo " format Format code (make fmt)"
|
|
1620
|
-
;;
|
|
1621
|
-
*)
|
|
1622
|
-
if [ -n "$CMD" ]; then
|
|
1623
|
-
echo "rapidkit: unknown command: $CMD" >&2
|
|
1624
|
-
fi
|
|
1625
|
-
echo "Available: init, dev, start, build, docs, test, lint, format" >&2
|
|
1626
|
-
exit 1
|
|
1627
|
-
;;
|
|
1628
|
-
esac
|
|
1629
|
-
`}function X(e){return `@echo off
|
|
1630
|
-
rem RapidKit Go/Gin project launcher \u2014 Windows
|
|
1631
|
-
set CMD=%1
|
|
1632
|
-
if "%CMD%"=="" goto usage
|
|
1633
|
-
shift
|
|
1634
|
-
|
|
1635
|
-
if "%CMD%"=="init" (
|
|
1636
|
-
echo Initializing Go/Gin project...
|
|
1637
|
-
go install github.com/air-verse/air@latest
|
|
1638
|
-
go install github.com/swaggo/swag/cmd/swag@latest
|
|
1639
|
-
if not exist .env if exist .env.example copy .env.example .env
|
|
1640
|
-
go mod tidy
|
|
1641
|
-
exit /b %ERRORLEVEL%
|
|
1642
|
-
)
|
|
1643
|
-
if "%CMD%"=="dev" ( make dev %* & exit /b %ERRORLEVEL% )
|
|
1644
|
-
if "%CMD%"=="build" ( make build %* & exit /b %ERRORLEVEL% )
|
|
1645
|
-
if "%CMD%"=="test" ( make test %* & exit /b %ERRORLEVEL% )
|
|
1646
|
-
if "%CMD%"=="lint" ( make lint %* & exit /b %ERRORLEVEL% )
|
|
1647
|
-
if "%CMD%"=="format" ( make fmt %* & exit /b %ERRORLEVEL% )
|
|
1648
|
-
if "%CMD%"=="docs" ( make docs %* & exit /b %ERRORLEVEL% )
|
|
1649
|
-
if "%CMD%"=="start" ( bin\\${e.project_name}.exe %* & exit /b %ERRORLEVEL% )
|
|
1650
|
-
|
|
1651
|
-
:usage
|
|
1652
|
-
echo Available: init, dev, start, build, docs, test, lint, format
|
|
1653
|
-
exit /b 1
|
|
1654
|
-
`}async function ne(e,o){let r={project_name:o.project_name,module_path:o.module_path||o.project_name,author:o.author||"RapidKit User",description:o.description||`Go/Gin REST API \u2014 ${o.project_name}`,go_version:o.go_version||"1.24",app_version:o.app_version||"0.1.0",port:o.port||"8080",skipGit:o.skipGit??false},g=b$1();try{await execa("go",["version"],{timeout:3e3});}catch{console.log(n.yellow("\n\u26A0 Go not found in PATH \u2014 project will be scaffolded, but `go mod tidy` requires Go 1.21+")),console.log(n.gray(` Install: https://go.dev/dl/
|
|
1655
|
-
`));}let i=f(`Generating Go/Gin project: ${r.project_name}\u2026`).start();try{let t=(m,h)=>w(s.join(e,m),h),u=s.join(e,"rapidkit"),p=s.join(e,"rapidkit.cmd");await Promise.all([t("cmd/server/main.go",v(r)),t("go.mod",R(r)),t("internal/config/config.go",S(r)),t("internal/server/server.go",b(r)),t("internal/middleware/requestid.go",I()),t("internal/middleware/requestid_test.go",L(r)),t("internal/apierr/apierr.go",x()),t("internal/apierr/apierr_test.go",k(r)),t("internal/handlers/health.go",T()),t("internal/handlers/health_test.go",_(r)),t("internal/handlers/example.go",D(r)),t("internal/handlers/example_test.go",P(r)),t("internal/config/config_test.go",A(r)),t("internal/middleware/cors.go",H()),t("internal/middleware/cors_test.go",$(r)),t("internal/middleware/ratelimit.go",j(r)),t("internal/middleware/ratelimit_test.go",U(r)),t("internal/server/server_test.go",F(r)),t("docs/doc.go",M(r)),t(".air.toml",B(r)),t("Dockerfile",O()),t("docker-compose.yml",N(r)),t("Makefile",E(r)),t(".golangci.yml",V(r.module_path)),t(".env.example",G(r)),t(".gitignore",q()),t(".github/workflows/ci.yml",C(r)),t("README.md",y(r)),t(".rapidkit/project.json",J(r,g)),t(".rapidkit/context.json",W()),t("rapidkit",K(r)),t("rapidkit.cmd",X(r))]),await promises.chmod(u,493),await promises.chmod(p,493),i.succeed(n.green(`Project created at ${e}`));try{i.start("Fetching Go dependencies\u2026"),await execa("go",["mod","tidy"],{cwd:e,timeout:12e4}),i.succeed(n.gray("\u2713 go mod tidy completed"));}catch{i.warn(n.yellow("\u26A0 go mod tidy failed \u2014 run manually: go mod tidy"));}if(!r.skipGit)try{await execa("git",["init"],{cwd:e}),await execa("git",["add","-A"],{cwd:e}),await execa("git",["commit","-m","chore: initial scaffold (rapidkit gogin.standard)"],{cwd:e}),console.log(n.gray("\u2713 git repository initialized"));}catch{console.log(n.gray("\u26A0 git init skipped (git not found or error)"));}console.log(""),console.log(n.bold("\u2705 Go/Gin project ready!")),console.log(""),console.log(n.cyan("Next steps:")),console.log(n.white(` cd ${r.project_name}`)),console.log(n.white(" make run # start dev server")),console.log(n.white(" make test # run tests")),console.log(""),console.log(n.gray("Server will listen on port "+r.port)),console.log(n.gray(" http://localhost:"+r.port+"/api/v1/health/live")),console.log(n.gray(" http://localhost:"+r.port+"/api/v1/health/ready")),console.log(""),console.log(n.yellow("\u2139 RapidKit modules are not available for Go projects (module system uses Python/pip).")),console.log("");}catch(t){throw i.fail(n.red("Failed to generate Go/Gin project")),t}}
|
|
1656
|
-
export{ne as generateGoGinKit};
|
|
1457
|
+
`}function Q(){return JSON.stringify({engine:"npm",runtime:"go"},null,2)}function z(e,n){return JSON.stringify({kit_name:"gogin.standard",runtime:"go",module_support:false,project_name:e.project_name,module_path:e.module_path,app_version:e.app_version,created_by:"rapidkit-npm",rapidkit_version:n,created_at:new Date().toISOString()},null,2)}function Y(e$1){return e({runtimeLabel:"Go/Gin",projectName:e$1.project_name,fallbackDevCommand:'cd "$SCRIPT_DIR" && GIN_MODE=debug exec go run ./cmd/server "$@"'})}function Z(e){return f({runtimeLabel:"Go/Gin",projectName:e.project_name})}async function ce(e,n){let r={project_name:n.project_name,module_path:n.module_path||n.project_name,author:n.author||"RapidKit User",description:n.description||`Go/Gin REST API \u2014 ${n.project_name}`,go_version:n.go_version||a,app_version:n.app_version||"0.1.0",port:n.port||"8080",skipGit:n.skipGit??false},f=b$1();try{await execa("go",["version"],{timeout:3e3});}catch{console.log(o.yellow("\n\u26A0 Go not found in PATH \u2014 project will be scaffolded, but `go mod tidy` requires Go 1.21+")),console.log(o.gray(` Install: https://go.dev/dl/
|
|
1458
|
+
`));}let i=_(`Generating Go/Gin project: ${r.project_name}\u2026`).start();try{let t=(v,S)=>c(d.join(e,v),S),w=d.join(e,"rapidkit"),R=d.join(e,"rapidkit.cmd");await Promise.all([t("cmd/server/main.go",T(r)),t("go.mod",O(r)),t("internal/config/config.go",N(r)),t("internal/server/server.go",b(r)),t("internal/middleware/requestid.go",k()),t("internal/middleware/requestid_test.go",A(r)),t("internal/apierr/apierr.go",P()),t("internal/apierr/apierr_test.go",D(r)),t("internal/handlers/health.go",G()),t("internal/handlers/health_test.go",q(r)),t("internal/handlers/example.go",F(r)),t("internal/handlers/example_test.go",$(r)),t("internal/config/config_test.go",j(r)),t("internal/middleware/cors.go",U()),t("internal/middleware/cors_test.go",B(r)),t("internal/middleware/ratelimit.go",W(r)),t("internal/middleware/ratelimit_test.go",J(r)),t("internal/server/server_test.go",V(r)),t("docs/doc.go",H(r)),t(".air.toml",K(r)),t("Dockerfile",E()),t("docker-compose.yml",L(r)),t("Makefile",C(r)),t(".golangci.yml",X(r.module_path)),t(".env.example",y(r)),t(".gitignore",I()),t(".github/workflows/ci.yml",x(r)),t("README.md",M(r)),t(".rapidkit/project.json",z(r,f)),t(".rapidkit/context.json",Q()),t("rapidkit",Y(r)),t("rapidkit.cmd",Z(r))]),await promises.chmod(w,493),await promises.chmod(R,493),i.succeed(o.green(`Project created at ${e}`));try{i.start("Fetching Go dependencies\u2026"),await execa("go",["mod","tidy"],{cwd:e,timeout:12e4}),i.succeed(o.gray("\u2713 go mod tidy completed"));}catch{i.warn(o.yellow("\u26A0 go mod tidy failed \u2014 run manually: go mod tidy"));}if(!r.skipGit)try{await execa("git",["init"],{cwd:e}),await execa("git",["add","-A"],{cwd:e}),await execa("git",["commit","-m","chore: initial scaffold (rapidkit gogin.standard)"],{cwd:e}),console.log(o.gray("\u2713 git repository initialized"));}catch{console.log(o.gray("\u26A0 git init skipped (git not found or error)"));}console.log(""),console.log(o.bold("\u2705 Go/Gin project ready!")),console.log(""),console.log(o.cyan("Next steps:")),console.log(o.white(` cd ${r.project_name}`)),console.log(o.white(" make run # start dev server")),console.log(o.white(" make test # run tests")),console.log(""),console.log(o.gray("Server will listen on port "+r.port)),console.log(o.gray(" http://localhost:"+r.port+"/api/v1/health/live")),console.log(o.gray(" http://localhost:"+r.port+"/api/v1/health/ready")),console.log(""),console.log(o.yellow("\u2139 RapidKit modules are not available for Go projects (module system uses Python/pip).")),console.log("");}catch(t){throw i.fail(o.red("Failed to generate Go/Gin project")),t}}
|
|
1459
|
+
export{ce as generateGoGinKit};
|
package/dist/index.js
CHANGED
|
@@ -103,10 +103,10 @@ No modules selected
|
|
|
103
103
|
`,"utf-8"),r.lockWritten=true,o.push({id:"mirror.lock.write",status:"passed",message:`Mirror lock updated at ${f.relative(t,a)}.`}),r.transparencyEvidenceRecords=fe.length,fe.length>0){let U={schemaVersion:"1.0",generatedAt:new Date().toISOString(),environment:_,records:fe},D=new Date().toISOString().replace(/[:.]/g,"-"),k=f.join(m,`transparency-evidence-${D}.json`),Q=f.join(m,"transparency-evidence.latest.json");if(await x.ensureDir(m),await ho(k,U),await ho(Q,U),r.transparencyEvidenceWritten=true,o.push({id:"sigstore.evidence.write",status:"passed",message:`Transparency evidence written to ${f.relative(t,Q)}.`}),b?.enabled){let Z=Math.max(1e3,b.timeoutMs??1e4);if(b.target==="file")if(!b.filePath)o.push({id:"sigstore.evidence.export.file",status:"failed",message:"Evidence export target=file requires security.evidenceExport.filePath."});else try{let K=me(t,b.filePath);await x.ensureDir(f.dirname(K)),await promises.appendFile(K,`${JSON.stringify(U)}
|
|
104
104
|
`,"utf-8"),r.evidenceExported=true,r.evidenceExportTarget=K,o.push({id:"sigstore.evidence.export.file",status:"passed",message:`Transparency evidence exported to file sink ${K}.`});}catch(K){o.push({id:"sigstore.evidence.export.file",status:"failed",message:`Evidence file export failed: ${K.message}`});}else if(b.target==="http")if(!b.endpoint)o.push({id:"sigstore.evidence.export.http",status:"failed",message:"Evidence export target=http requires security.evidenceExport.endpoint."});else {let K=Math.max(0,b.retries??0),B=Math.max(0,b.backoffMs??500),ee=Or(U,b.signing);ee.error&&o.push({id:"sigstore.evidence.export.http",status:"failed",message:ee.error});try{let C=b.authTokenEnv?process.env[b.authTokenEnv]:void 0,R=false,O=null;for(let j=1;j<=K+1;j+=1)try{if(ee.error)throw new Error(ee.error);await $r(b.endpoint,U,Z,C,ee.headers),r.evidenceExported=true,r.evidenceExportTarget=b.endpoint,o.push({id:"sigstore.evidence.export.http",status:"passed",message:j>1?`Transparency evidence exported to HTTP endpoint ${b.endpoint} after ${j} attempts.`:`Transparency evidence exported to HTTP endpoint ${b.endpoint}.`}),R=true;break}catch(Y){O=Y,j<=K&&await wo(B*j);}if(!R)throw O||new Error("unknown evidence export error")}catch(C){let R=`Evidence HTTP export failed: ${C.message}`;o.push({id:"sigstore.evidence.export.http",status:"failed",message:R});try{let O=await Tr(t,b.deadLetterPath,U,R);o.push({id:"sigstore.evidence.export.deadletter",status:"passed",message:`Evidence export failure persisted to dead-letter sink ${O}.`});}catch(O){o.push({id:"sigstore.evidence.export.deadletter",status:"failed",message:`Evidence dead-letter write failed: ${O.message}`});}}}if(b.failOnError&&o.some(B=>B.status==="failed"&&(B.id==="sigstore.evidence.export.file"||B.id==="sigstore.evidence.export.http")))return {checks:o,details:r}}else o.push({id:"sigstore.evidence.export",status:"skipped",message:"Central evidence export not configured (security.evidenceExport.enabled=false)."});}else o.push({id:"sigstore.evidence.write",status:"skipped",message:"No Sigstore records available for transparency evidence output."}),o.push({id:"sigstore.evidence.export",status:"skipped",message:"Central evidence export skipped because no transparency evidence records exist."});return {checks:o,details:r}}function Et(t){if(!t||typeof t!="object")return null;let e=t.code;return e==="PYTHON_NOT_FOUND"||e==="BRIDGE_VENV_BOOTSTRAP_FAILED"?e:null}function Lr(t){let e=t.trim().toLowerCase();return e?e.startsWith("fastapi")?"fastapi":e.startsWith("nestjs")?"nestjs":null:null}function ht(t){let e=t.trim().toLowerCase();return e.startsWith("gofiber")||e==="go"||e==="go.standard"||e==="fiber"}function Ue(t){let e=t.trim().toLowerCase();return e.startsWith("gogin")||e==="gin"}function Je(t,e){let o=t.indexOf(e);if(o>=0&&o+1<t.length)return t[o+1];let r=t.find(n=>n.startsWith(`${e}=`));if(r)return r.slice(e.length+1)}function Ot(){return d$1()}function _o(){let t={...process.env},e=t.PATH||"";return e&&(t.PATH=e.split(f.delimiter).filter(o=>!o.replace(/\\/g,"/").includes("/.pyenv/shims")).join(f.delimiter)),t.PYENV_VERSION="system",t.POETRY_PYTHON||(t.POETRY_PYTHON=c$2()),t.RAPIDKIT_SKIP_LOCK_SYNC||(t.RAPIDKIT_SKIP_LOCK_SYNC="1"),t.POETRY_KEYRING_ENABLED||(t.POETRY_KEYRING_ENABLED="false"),t.PYTHON_KEYRING_BACKEND||(t.PYTHON_KEYRING_BACKEND="keyring.backends.null.Keyring"),t.POETRY_NO_INTERACTION||(t.POETRY_NO_INTERACTION="1"),t}function Fr(t){return f$1(f.join(t,".venv"))}async function Do(t,e){return await F(t,["--version"],e)===0}async function At(t){let e=f.join(t,"go.mod");if(await x__default.pathExists(e))return "go";let o=f.join(t,"package.json");if(await x__default.pathExists(o))return "node";let r=f.join(t,"pyproject.toml"),n=f.join(t,"requirements.txt"),i=f.join(t,"poetry.lock");return await x__default.pathExists(r)||await x__default.pathExists(n)||await x__default.pathExists(i)?"python":null}async function Wr(t){for(let e of Ot())if(await F(e,e==="py"?["-3","-m","venv",".venv"]:["-m","venv",".venv"],t)===0)return 0;return 1}async function No(t){for(let e of Ot())if(await F(e,e==="py"?["-3","-m","venv",".venv"]:["-m","venv",".venv"],t)===0)return 0;return 1}async function Gr(t){let e=f$1(f.join(t,".venv"));if(!await x__default.pathExists(e)){let i=await No(t);if(i!==0)return i}if(!await Do("poetry",t))return 0;let r=await F("poetry",["config","virtualenvs.in-project","true","--local"],t);if(r!==0)return r;let n=await F("poetry",["env","use",e],t);return n!==0?n:0}async function qr(t){let e=f$1(f.join(t,".venv"));if(!await x__default.pathExists(e)){let n=await No(t);if(n!==0)return n}await F(e,["-m","pip","install","--upgrade","pip","setuptools","wheel"],t);let o=f.join(t,"requirements.txt");if(await x__default.pathExists(o)&&await F(e,["-m","pip","install","-r","requirements.txt"],t)===0)return 0;let r=f.join(t,"pyproject.toml");return await x__default.pathExists(r)&&(await F(e,["-m","pip","install","-e","."],t)===0||await F(e,["-m","pip","install","."],t)===0)?0:1}async function mt(t,e){return await Gr(t)!==0&&console.log(s.yellow("\u26A0\uFE0F Could not fully configure Poetry local venv. Trying fallback installer...")),(await e.initProject(t)).exitCode===0&&await x__default.pathExists(f.join(t,".venv"))?0:(console.log(s.yellow("\u26A0\uFE0F Python init fallback: installing dependencies directly into project .venv")),await qr(t))}async function ft(t){let e=await He("init",t);if(e===0)return 0;let o=["npm","pnpm","yarn"];for(let r of o){if(!await Do(r,t))continue;if(await F(r,["install"],t)===0)return console.log(s.green(`\u2705 Node init fallback succeeded with ${r} install`)),0}return e}async function xo(t){if(t[0]!=="create"||t[1]!=="project")return 1;let e=t[2],o=t[3];if(!e||!o)return process.stderr.write(`Usage: rapidkit create project gofiber.standard <name> [--output <dir>]
|
|
105
105
|
`),1;let r=Je(t,"--output")||process.cwd(),n=f.resolve(r,o),i=t.includes("--skip-git")||t.includes("--no-git");try{let{default:a}=await import('fs-extra');if(await a.ensureDir(f.dirname(n)),await a.pathExists(n))return process.stderr.write(`\u274C Directory "${n}" already exists
|
|
106
|
-
`),1;await a.ensureDir(n);let{generateGoFiberKit:c}=await import('./gofiber-standard-
|
|
106
|
+
`),1;await a.ensureDir(n);let{generateGoFiberKit:c}=await import('./gofiber-standard-JDPREQCP.js');await c(n,{project_name:o,module_path:o,skipGit:i});let m=q(process.cwd());if(m){let{syncWorkspaceProjects:d}=await import('./workspace-VXNLNKCM.js');await d(m,true);}return 0}catch(a){return process.stderr.write(`RapidKit Go/Fiber generator failed: ${a?.message??a}
|
|
107
107
|
`),1}}async function Ro(t){if(t[0]!=="create"||t[1]!=="project")return 1;let e=t[2],o=t[3];if(!e||!o)return process.stderr.write(`Usage: rapidkit create project gogin.standard <name> [--output <dir>]
|
|
108
108
|
`),1;let r=Je(t,"--output")||process.cwd(),n=f.resolve(r,o),i=t.includes("--skip-git")||t.includes("--no-git");try{let{default:a}=await import('fs-extra');if(await a.ensureDir(f.dirname(n)),await a.pathExists(n))return process.stderr.write(`\u274C Directory "${n}" already exists
|
|
109
|
-
`),1;await a.ensureDir(n);let{generateGoGinKit:c}=await import('./gogin-standard-
|
|
109
|
+
`),1;await a.ensureDir(n);let{generateGoGinKit:c}=await import('./gogin-standard-DCERHHVB.js');await c(n,{project_name:o,module_path:o,skipGit:i});let m=q(process.cwd());if(m){let{syncWorkspaceProjects:d}=await import('./workspace-VXNLNKCM.js');await d(m,true);}return 0}catch(a){return process.stderr.write(`RapidKit Go/Gin generator failed: ${a?.message??a}
|
|
110
110
|
`),1}}async function It(t,e){if(t.includes("--json"))return process.stderr.write("RapidKit (npm) offline fallback does not support --json for `create` commands.\nInstall Python 3.10+ and retry the same command.\n"),1;if(t[0]!=="create")return 1;if(t[1]!=="project")return process.stderr.write(`RapidKit (npm) could not run the Python core engine for \`create\`.
|
|
111
111
|
Reason: ${e}.
|
|
112
112
|
Install Python 3.10+ to use the interactive wizard and full kit catalog.
|
|
@@ -223,11 +223,11 @@ Use "rapidkit help <command>" for more information.
|
|
|
223
223
|
`)),process.exit(1));let a=!!e$2.template;if(e$2.dryRun){console.log(s.cyan(`
|
|
224
224
|
\u{1F50D} Dry-run mode - showing what would be created:
|
|
225
225
|
`)),console.log(s.white("\u{1F4C2} Path:"),i),console.log(s.white("\u{1F4E6} Type:"),a?`Project (${e$2.template})`:"Workspace"),console.log();return}if(!e$2.yes&&!a?await he.prompt([{type:"input",name:"author",message:"Author name:",default:process.env.USER||"RapidKit User"}]):e$2.yes&&console.log(s.gray(`Using default values (--yes flag)
|
|
226
|
-
`)),a){let c=String(e$2.template||"").trim(),m=c.toLowerCase(),d$1=m==="fastapi"?"fastapi.standard":m==="nestjs"?"nestjs.standard":m==="go"||m==="fiber"?"gofiber.standard":m==="gin"?"gogin.standard":c;if(ht(d$1)){let S=f.resolve(process.cwd(),t),{generateGoFiberKit:b}=await import('./gofiber-standard-
|
|
226
|
+
`)),a){let c=String(e$2.template||"").trim(),m=c.toLowerCase(),d$1=m==="fastapi"?"fastapi.standard":m==="nestjs"?"nestjs.standard":m==="go"||m==="fiber"?"gofiber.standard":m==="gin"?"gogin.standard":c;if(ht(d$1)){let S=f.resolve(process.cwd(),t),{generateGoFiberKit:b}=await import('./gofiber-standard-JDPREQCP.js');await b(S,{project_name:t,module_path:t,skipGit:e$2.skipGit});return}if(Ue(d$1)){let S=f.resolve(process.cwd(),t),{generateGoGinKit:b}=await import('./gogin-standard-DCERHHVB.js');await b(S,{project_name:t,module_path:t,skipGit:e$2.skipGit});return}if(!!!$t(process.cwd())){let{registerWorkspaceAtPath:S}=await import('./create-27NVMJAR.js');if(e$2.createWorkspace)await S(process.cwd(),{skipGit:e$2.skipGit,yes:e$2.yes,userConfig:o});else if(!e$2.noWorkspace)if(e$2.yes)await S(process.cwd(),{skipGit:e$2.skipGit,yes:true,userConfig:o});else {let{createWs:b}=await he.prompt([{type:"confirm",name:"createWs",message:"This project will be created outside a RapidKit workspace. Create and register a workspace here?",default:true}]);b&&await S(process.cwd(),{skipGit:e$2.skipGit,yes:false,userConfig:o});}}let u=["create","project",d$1,t,"--output",process.cwd()];e$2.yes&&u.push("--yes");let y=q(process.cwd()),v=!!e$2.skipInstall,p=v||!!y;v&&u.push("--skip-essentials");let g=p?{...process.env,RAPIDKIT_SKIP_LOCKS:"1",RAPIDKIT_GENERATE_LOCKS:"0"}:void 0,A=await e$1(u,{cwd:process.cwd(),env:g});A!==0&&process.exit(A),y&&!e$2.skipInstall&&(console.log(s.gray("\u2139\uFE0F Fast create mode (workspace): dependencies were deferred.")),console.log(s.white(" Next: cd <project-name> && npx rapidkit init")));let P=$t(process.cwd());if(P){let S=f.dirname(P),b=f.join(S,".python-version"),_=f.join(i,".python-version");try{if(await x__default.pathExists(b)){let M=w.readFileSync(b,"utf-8");w.writeFileSync(_,M.trim()+`
|
|
227
227
|
`),a$1.debug(`Synced Python version ${M.trim()} from workspace to project`);}}catch(M){a$1.debug("Could not sync Python version from workspace:",M);}}if(!e$2.skipInstall){let S=await d(["init",i],{cwd:process.cwd()});if(S!==0&&process.exit(S),P){let b=f.dirname(P),_=f.join(b,".python-version"),M=f.join(i,".python-version");try{if(await x__default.pathExists(_)){let T=w.readFileSync(_,"utf-8");w.writeFileSync(M,T.trim()+`
|
|
228
228
|
`),a$1.debug(`Re-synced Python version ${T.trim()} after init`);}}catch(T){a$1.debug("Could not re-sync Python version after init:",T);}}}}else {let{createProject:c}=await import('./create-27NVMJAR.js');await c(t,{skipGit:e$2.skipGit,dryRun:e$2.dryRun,yes:e$2.yes,userConfig:n,installMethod:e$2.installMethod,profile:e$2.profile});}}catch(o){o instanceof e?(a$1.error(`
|
|
229
229
|
\u274C ${o.message}`),o.details&&a$1.warn(`\u{1F4A1} ${o.details}`),a$1.debug("Error code:",o.code)):(a$1.error(`
|
|
230
|
-
\u274C An unexpected error occurred:`),console.error(o)),process.exit(1);}finally{Pe=null;}});mo(ce);Vt(ce);ce.command("shell <action>").description("Shell helpers (activate virtualenv in current shell)").action(async t=>{t!=="activate"&&(console.log(s.red(`Unknown shell command: ${t}`)),process.exit(1));let e=process.cwd();function o(m){let d=m;for(;;){let l=f.join(d,".rapidkit","context.json");if(w.existsSync(l))return l;let u=f.dirname(d);if(u===d)break;d=u;}return null}let r=o(e);function n(m){let d=m;for(;;){let l=f.join(d,".venv"),u=f.join(d,".rapidkit","activate");if(w.existsSync(u)||w.existsSync(l))return {venv:l,activateFile:u};let y=f.dirname(d);if(y===d)break;d=y;}return null}let i=n(e);!r&&!i&&(console.log(s.yellow("No RapidKit project found in this directory")),process.exit(1));let a$1;i&&w.existsSync(i.activateFile)?a$1=i.activateFile:i&&w.existsSync(i.venv)?a$1=h(i.venv):(console.log(s.yellow("No virtual environment found")),process.exit(1));let c=a();console.log(c?`call "${a$1}"`:`. "${a$1}"`);});ce.command("doctor [scope]").description("\u{1FA7A} Check RapidKit system health by default; use workspace for full workspace checks").option("--workspace","Check entire workspace (including all projects)").option("--json","Output results in JSON format (for CI/CD pipelines)").option("--fix","Automatically fix common issues (with confirmation)").action(async(t,e)=>{t&&t!=="workspace"&&(console.log(s.red(`Unknown doctor scope: ${t}`)),console.log(s.gray("Available: workspace")),console.log(s.gray("Usage: npx rapidkit doctor or npx rapidkit doctor workspace")),process.exit(1));let o=await Yr({scope:t,workspaceFlag:e.workspace});o.detected&&!e.json&&(console.log(s.yellow("\u26A0\uFE0F Local launcher shadow detected for doctor workspace checks.")),o.candidatePath&&console.log(s.gray(` Candidate: ${o.candidatePath}`)),console.log(s.gray(" Running npm-wrapper doctor workflow directly as safe fallback to avoid ambiguous rapidkit binary resolution.")));let{runDoctor:r}=await import('./doctor-P57TTWEP.js');await r({...e,workspace:e.workspace||t==="workspace"});});ce.command("workspace <action> [subaction] [key] [value]").description("Manage RapidKit workspaces (list, sync, policy)").action(async(t,e,o,r)=>{if(t==="list"){let{listWorkspaces:n}=await import('./workspace-VXNLNKCM.js');await n();}else if(t==="sync"){let n=q(process.cwd());n||(console.log(s.red("\u274C Not inside a RapidKit workspace")),console.log(s.gray("\u{1F4A1} Run this command from within a workspace directory")),process.exit(1));let{syncWorkspaceProjects:i}=await import('./workspace-VXNLNKCM.js');console.log(s.cyan(`\u{1F4C2} Scanning workspace: ${f.basename(n)}`)),await i(n);}else if(t==="policy"){let n=q(process.cwd());n||(console.log(s.red("\u274C Not inside a RapidKit workspace")),console.log(s.gray("\u{1F4A1} Run this command from within a workspace directory")),process.exit(1));let i=await ln(n,e,o,r);i!==0&&process.exit(i);}else console.log(s.red(`Unknown workspace action: ${t}`)),console.log(s.gray("Available: list, sync, policy")),process.exit(1);});function Bo(){let t=a()?"npx rapidkit init; npx rapidkit dev":"npx rapidkit init && npx rapidkit dev";console.log(s.white(`Usage:
|
|
230
|
+
\u274C An unexpected error occurred:`),console.error(o)),process.exit(1);}finally{Pe=null;}});mo(ce);Vt(ce);ce.command("shell <action>").description("Shell helpers (activate virtualenv in current shell)").action(async t=>{t!=="activate"&&(console.log(s.red(`Unknown shell command: ${t}`)),process.exit(1));let e=process.cwd();function o(m){let d=m;for(;;){let l=f.join(d,".rapidkit","context.json");if(w.existsSync(l))return l;let u=f.dirname(d);if(u===d)break;d=u;}return null}let r=o(e);function n(m){let d=m;for(;;){let l=f.join(d,".venv"),u=f.join(d,".rapidkit","activate");if(w.existsSync(u)||w.existsSync(l))return {venv:l,activateFile:u};let y=f.dirname(d);if(y===d)break;d=y;}return null}let i=n(e);!r&&!i&&(console.log(s.yellow("No RapidKit project found in this directory")),process.exit(1));let a$1;i&&w.existsSync(i.activateFile)?a$1=i.activateFile:i&&w.existsSync(i.venv)?a$1=h(i.venv):(console.log(s.yellow("No virtual environment found")),process.exit(1));let c=a();console.log(c?`call "${a$1}"`:`. "${a$1}"`);});ce.command("doctor [scope]").description("\u{1FA7A} Check RapidKit system health by default; use workspace for full workspace checks").option("--workspace","Check entire workspace (including all projects)").option("--json","Output results in JSON format (for CI/CD pipelines)").option("--fix","Automatically fix common issues (with confirmation)").action(async(t,e)=>{t&&t!=="workspace"&&(console.log(s.red(`Unknown doctor scope: ${t}`)),console.log(s.gray("Available: workspace")),console.log(s.gray("Usage: npx rapidkit doctor or npx rapidkit doctor workspace")),process.exit(1));let o=await Yr({scope:t,workspaceFlag:e.workspace});o.detected&&!e.json&&(console.log(s.yellow("\u26A0\uFE0F Local launcher shadow detected for doctor workspace checks.")),o.candidatePath&&console.log(s.gray(` Candidate: ${o.candidatePath}`)),console.log(s.gray(" Running npm-wrapper doctor workflow directly as safe fallback to avoid ambiguous rapidkit binary resolution.")),console.log(s.gray(" If this happens in a shell call, run: npx --yes --package rapidkit rapidkit doctor workspace")));let{runDoctor:r}=await import('./doctor-P57TTWEP.js');await r({...e,workspace:e.workspace||t==="workspace"});});ce.command("workspace <action> [subaction] [key] [value]").description("Manage RapidKit workspaces (list, sync, policy)").action(async(t,e,o,r)=>{if(t==="list"){let{listWorkspaces:n}=await import('./workspace-VXNLNKCM.js');await n();}else if(t==="sync"){let n=q(process.cwd());n||(console.log(s.red("\u274C Not inside a RapidKit workspace")),console.log(s.gray("\u{1F4A1} Run this command from within a workspace directory")),process.exit(1));let{syncWorkspaceProjects:i}=await import('./workspace-VXNLNKCM.js');console.log(s.cyan(`\u{1F4C2} Scanning workspace: ${f.basename(n)}`)),await i(n);}else if(t==="policy"){let n=q(process.cwd());n||(console.log(s.red("\u274C Not inside a RapidKit workspace")),console.log(s.gray("\u{1F4A1} Run this command from within a workspace directory")),process.exit(1));let i=await ln(n,e,o,r);i!==0&&process.exit(i);}else console.log(s.red(`Unknown workspace action: ${t}`)),console.log(s.gray("Available: list, sync, policy")),process.exit(1);});function Bo(){let t=a()?"npx rapidkit init; npx rapidkit dev":"npx rapidkit init && npx rapidkit dev";console.log(s.white(`Usage:
|
|
231
231
|
`)),console.log(s.cyan(` npx rapidkit <workspace-name> [options]
|
|
232
232
|
`)),console.log(s.bold("Quick start \u2014 workspace workflow:")),console.log(s.cyan(" npx rapidkit my-workspace ")+s.gray("# Create workspace (interactive profile picker)")),console.log(s.cyan(" cd my-workspace")),console.log(s.cyan(" npx rapidkit bootstrap ")+s.gray("# Bootstrap all runtime toolchains")),console.log(s.cyan(" npx rapidkit create project ")+s.gray("# Interactive kit picker")),console.log(s.cyan(" cd my-api")),console.log(s.cyan(` ${t}
|
|
233
233
|
`)),console.log(s.bold("Workspace profiles (asked during creation):")),console.log(s.gray(" minimal Foundation files only \u2014 fastest bootstrap (default)")),console.log(s.gray(" python-only Python + Poetry (FastAPI, Django, ML)")),console.log(s.gray(" node-only Node.js runtime (NestJS, Express, Next.js)")),console.log(s.gray(" go-only Go runtime (Fiber, Gin, gRPC)")),console.log(s.gray(" polyglot Python + Node.js + Go multi-runtime")),console.log(s.gray(` enterprise Polyglot + governance + Sigstore
|
package/dist/package.json
CHANGED
package/package.json
CHANGED