@robsun/create-keystone-app 0.1.13 → 0.1.15

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.
Files changed (55) hide show
  1. package/README.md +19 -10
  2. package/bin/create-keystone-app.js +199 -60
  3. package/package.json +1 -1
  4. package/template/.husky/pre-commit +4 -0
  5. package/template/.lintstagedrc.json +5 -0
  6. package/template/.prettierrc +9 -0
  7. package/template/README.md +45 -23
  8. package/template/apps/server/.air.toml +44 -0
  9. package/template/apps/server/README.md +27 -0
  10. package/template/apps/server/cmd/server/main.go +213 -0
  11. package/template/apps/server/config.yaml +51 -0
  12. package/template/apps/server/docs/docs.go +34 -0
  13. package/template/apps/server/go.mod +13 -0
  14. package/template/apps/server/go.sum +72 -0
  15. package/template/apps/server/internal/app/routes/module_routes.go +16 -0
  16. package/template/apps/server/internal/app/routes/routes.go +226 -0
  17. package/template/apps/server/internal/app/startup/startup.go +74 -0
  18. package/template/apps/server/internal/frontend/dist/.gitkeep +1 -0
  19. package/template/apps/server/internal/frontend/embed.go +28 -0
  20. package/template/apps/server/internal/frontend/handler.go +122 -0
  21. package/template/apps/server/internal/{demo/demo.go → modules/demo/handlers.go} +4 -1
  22. package/template/apps/server/internal/modules/demo/module.go +55 -0
  23. package/template/apps/server/internal/modules/manifest.go +11 -0
  24. package/template/apps/server/internal/modules/registry.go +145 -0
  25. package/template/apps/web/.env.example +3 -0
  26. package/template/apps/web/README.md +29 -0
  27. package/template/apps/web/eslint.config.js +35 -0
  28. package/template/apps/web/package.json +27 -10
  29. package/template/apps/web/postcss.config.js +6 -0
  30. package/template/apps/web/src/index.css +3 -0
  31. package/template/apps/web/src/main.tsx +1 -0
  32. package/template/apps/web/src/modules/demo/help/overview.md +12 -0
  33. package/template/apps/web/src/modules/demo/routes.tsx +2 -0
  34. package/template/apps/web/tailwind.config.js +18 -0
  35. package/template/apps/web/tests/setup.ts +37 -0
  36. package/template/apps/web/tsconfig.app.json +3 -3
  37. package/template/apps/web/vite.config.ts +28 -2
  38. package/template/docker-compose.yml +45 -0
  39. package/template/docs/CODE_STYLE.md +34 -0
  40. package/template/docs/CONVENTIONS.md +62 -88
  41. package/template/package.json +15 -3
  42. package/template/scripts/build.bat +133 -0
  43. package/template/scripts/build.js +25 -0
  44. package/template/scripts/build.sh +99 -0
  45. package/template/scripts/clean.bat +35 -0
  46. package/template/scripts/clean.js +25 -0
  47. package/template/scripts/clean.sh +34 -0
  48. package/template/scripts/dev.bat +82 -0
  49. package/template/scripts/dev.js +25 -0
  50. package/template/scripts/dev.sh +88 -0
  51. package/template/scripts/test.bat +86 -0
  52. package/template/scripts/test.js +25 -0
  53. package/template/scripts/test.sh +86 -0
  54. package/template/apps/server/main.go +0 -28
  55. /package/template/{config.yaml → apps/server/config.example.yaml} +0 -0
@@ -0,0 +1,133 @@
1
+ @echo off
2
+ setlocal enabledelayedexpansion
3
+
4
+ echo ========================================
5
+ echo Keystone Production Build
6
+ echo (Single Executable with Embedded Frontend)
7
+ echo ========================================
8
+ echo.
9
+
10
+ set "PROJECT_ROOT=%~dp0.."
11
+ set "FRONTEND_DIR=%PROJECT_ROOT%\apps\web"
12
+ set "BACKEND_DIR=%PROJECT_ROOT%\apps\server"
13
+ set "EMBED_DIR=%BACKEND_DIR%\internal\frontend\dist"
14
+ set "OUTPUT_DIR=%PROJECT_ROOT%\dist"
15
+ set "OUTPUT_NAME=__APP_NAME__"
16
+
17
+ echo Checking prerequisites...
18
+ where node >nul 2>&1
19
+ if errorlevel 1 (
20
+ echo [ERROR] Node.js is not installed
21
+ exit /b 1
22
+ )
23
+ echo [OK] Node.js found
24
+
25
+ where pnpm >nul 2>&1
26
+ if errorlevel 1 (
27
+ echo [ERROR] pnpm is not installed
28
+ exit /b 1
29
+ )
30
+ echo [OK] pnpm found
31
+
32
+ where go >nul 2>&1
33
+ if errorlevel 1 (
34
+ echo [ERROR] Go is not installed
35
+ exit /b 1
36
+ )
37
+ echo [OK] Go found
38
+
39
+ echo.
40
+ echo Building production artifacts...
41
+ echo.
42
+
43
+ if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
44
+ if not exist "%EMBED_DIR%" mkdir "%EMBED_DIR%"
45
+
46
+ set FAILED=0
47
+
48
+ echo ----------------------------------------
49
+ echo [1/4] Cleaning embed directory
50
+ echo ----------------------------------------
51
+ for /f "delims=" %%i in ('dir /b /a-d "%EMBED_DIR%\*" 2^>nul ^| findstr /v "^\.gitkeep$"') do del /q "%EMBED_DIR%\%%i" 2>nul
52
+ for /d %%i in ("%EMBED_DIR%\*") do rd /s /q "%%i" 2>nul
53
+ echo [OK] Embed directory cleaned
54
+
55
+ echo ----------------------------------------
56
+ echo [2/4] Building Frontend
57
+ echo ----------------------------------------
58
+ cd /d "%FRONTEND_DIR%"
59
+ call pnpm build
60
+ if errorlevel 1 (
61
+ echo [FAIL] Frontend build failed
62
+ set FAILED=1
63
+ cd /d "%PROJECT_ROOT%"
64
+ exit /b 1
65
+ )
66
+ echo [OK] Frontend build completed
67
+ cd /d "%PROJECT_ROOT%"
68
+
69
+ echo ----------------------------------------
70
+ echo [3/4] Building Backend (with embedded frontend)
71
+ echo ----------------------------------------
72
+ cd /d "%BACKEND_DIR%"
73
+
74
+ echo Building for Windows (amd64)...
75
+ set CGO_ENABLED=0
76
+ set GOOS=windows
77
+ set GOARCH=amd64
78
+ go build -ldflags="-s -w" -o "%OUTPUT_DIR%\%OUTPUT_NAME%.exe" ./cmd/server
79
+ if errorlevel 1 (
80
+ echo [FAIL] Windows build failed
81
+ set FAILED=1
82
+ cd /d "%PROJECT_ROOT%"
83
+ exit /b 1
84
+ )
85
+ echo [OK] Windows build completed
86
+
87
+ echo Building for Linux (amd64)...
88
+ set CGO_ENABLED=0
89
+ set GOOS=linux
90
+ set GOARCH=amd64
91
+ go build -ldflags="-s -w" -o "%OUTPUT_DIR%\%OUTPUT_NAME%" ./cmd/server
92
+ if errorlevel 1 (
93
+ echo [FAIL] Linux build failed
94
+ set FAILED=1
95
+ cd /d "%PROJECT_ROOT%"
96
+ exit /b 1
97
+ )
98
+ echo [OK] Linux build completed
99
+
100
+ cd /d "%PROJECT_ROOT%"
101
+
102
+ echo ----------------------------------------
103
+ echo [4/4] Copying configuration template
104
+ echo ----------------------------------------
105
+ if exist "%BACKEND_DIR%\config.example.yaml" (
106
+ copy /Y "%BACKEND_DIR%\config.example.yaml" "%OUTPUT_DIR%\config.example.yaml" >nul
107
+ echo [OK] Config template copied
108
+ )
109
+
110
+ echo.
111
+ echo ========================================
112
+ if "%FAILED%"=="1" goto :build_failed
113
+
114
+ echo Build completed successfully!
115
+ echo.
116
+ echo Executables (frontend embedded):
117
+ echo - dist\%OUTPUT_NAME%.exe (Windows)
118
+ echo - dist\%OUTPUT_NAME% (Linux)
119
+ echo.
120
+ echo Configuration:
121
+ echo - dist\config.example.yaml
122
+ echo.
123
+ echo Usage:
124
+ echo Windows: cd dist ^&^& %OUTPUT_NAME%.exe
125
+ echo Linux: cd dist ^&^& ./%OUTPUT_NAME%
126
+ goto :build_done
127
+
128
+ :build_failed
129
+ echo Build FAILED
130
+ exit /b 1
131
+
132
+ :build_done
133
+ echo ========================================
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ const { spawn } = require('child_process')
3
+ const path = require('path')
4
+ const os = require('os')
5
+
6
+ const scriptsDir = __dirname
7
+ const isWindows = os.platform() === 'win32'
8
+ const script = isWindows
9
+ ? path.join(scriptsDir, 'build.bat')
10
+ : path.join(scriptsDir, 'build.sh')
11
+
12
+ const child = spawn(script, [], {
13
+ stdio: 'inherit',
14
+ shell: true,
15
+ cwd: path.join(scriptsDir, '..'),
16
+ })
17
+
18
+ child.on('error', (err) => {
19
+ console.error('Failed to start build:', err)
20
+ process.exit(1)
21
+ })
22
+
23
+ child.on('exit', (code) => {
24
+ process.exit(code || 0)
25
+ })
@@ -0,0 +1,99 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "========================================"
5
+ echo " Keystone Production Build"
6
+ echo " (Single Executable with Embedded Frontend)"
7
+ echo "========================================"
8
+ echo ""
9
+
10
+ RED='\033[0;31m'
11
+ GREEN='\033[0;32m'
12
+ NC='\033[0m'
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
15
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
16
+ FRONTEND_DIR="$PROJECT_ROOT/apps/web"
17
+ BACKEND_DIR="$PROJECT_ROOT/apps/server"
18
+ EMBED_DIR="$BACKEND_DIR/internal/frontend/dist"
19
+ OUTPUT_DIR="$PROJECT_ROOT/dist"
20
+ OUTPUT_NAME="__APP_NAME__"
21
+
22
+ echo "Checking prerequisites..."
23
+ if ! command -v node &> /dev/null; then
24
+ echo -e "${RED}[ERROR]${NC} Node.js is not installed"
25
+ exit 1
26
+ fi
27
+ echo -e "${GREEN}[OK]${NC} Node.js found"
28
+
29
+ if ! command -v pnpm &> /dev/null; then
30
+ echo -e "${RED}[ERROR]${NC} pnpm is not installed"
31
+ exit 1
32
+ fi
33
+ echo -e "${GREEN}[OK]${NC} pnpm found"
34
+
35
+ if ! command -v go &> /dev/null; then
36
+ echo -e "${RED}[ERROR]${NC} Go is not installed"
37
+ exit 1
38
+ fi
39
+ echo -e "${GREEN}[OK]${NC} Go found"
40
+
41
+ echo ""
42
+ echo "Building production artifacts..."
43
+ echo ""
44
+
45
+ mkdir -p "$OUTPUT_DIR"
46
+ mkdir -p "$EMBED_DIR"
47
+
48
+ echo "----------------------------------------"
49
+ echo "[1/4] Cleaning embed directory"
50
+ echo "----------------------------------------"
51
+ find "$EMBED_DIR" -mindepth 1 ! -name '.gitkeep' -delete 2>/dev/null || true
52
+ echo -e "${GREEN}[OK]${NC} Embed directory cleaned"
53
+
54
+ echo "----------------------------------------"
55
+ echo "[2/4] Building Frontend"
56
+ echo "----------------------------------------"
57
+ cd "$FRONTEND_DIR"
58
+ pnpm build
59
+ echo -e "${GREEN}[OK]${NC} Frontend build completed"
60
+ cd "$PROJECT_ROOT"
61
+
62
+ echo "----------------------------------------"
63
+ echo "[3/4] Building Backend (with embedded frontend)"
64
+ echo "----------------------------------------"
65
+ cd "$BACKEND_DIR"
66
+
67
+ echo "Building for Windows (amd64)..."
68
+ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o "$OUTPUT_DIR/$OUTPUT_NAME.exe" ./cmd/server
69
+ echo -e "${GREEN}[OK]${NC} Windows build completed"
70
+
71
+ echo "Building for Linux (amd64)..."
72
+ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o "$OUTPUT_DIR/$OUTPUT_NAME" ./cmd/server
73
+ echo -e "${GREEN}[OK]${NC} Linux build completed"
74
+
75
+ cd "$PROJECT_ROOT"
76
+
77
+ echo "----------------------------------------"
78
+ echo "[4/4] Copying configuration template"
79
+ echo "----------------------------------------"
80
+ if [ -f "$BACKEND_DIR/config.example.yaml" ]; then
81
+ cp "$BACKEND_DIR/config.example.yaml" "$OUTPUT_DIR/config.example.yaml"
82
+ echo -e "${GREEN}[OK]${NC} Config template copied"
83
+ fi
84
+
85
+ echo ""
86
+ echo "========================================"
87
+ echo -e " ${GREEN}Build completed successfully!${NC}"
88
+ echo ""
89
+ echo " Executables (frontend embedded):"
90
+ echo " - $OUTPUT_DIR/$OUTPUT_NAME.exe (Windows)"
91
+ echo " - $OUTPUT_DIR/$OUTPUT_NAME (Linux)"
92
+ echo ""
93
+ echo " Configuration:"
94
+ echo " - $OUTPUT_DIR/config.example.yaml"
95
+ echo ""
96
+ echo " Usage:"
97
+ echo " Windows: cd dist && $OUTPUT_NAME.exe"
98
+ echo " Linux: cd dist && ./$OUTPUT_NAME"
99
+ echo "========================================"
@@ -0,0 +1,35 @@
1
+ @echo off
2
+ setlocal enabledelayedexpansion
3
+
4
+ echo ========================================
5
+ echo Keystone Clean
6
+ echo ========================================
7
+ echo.
8
+
9
+ echo Cleaning build artifacts...
10
+
11
+ if exist "dist" (
12
+ rmdir /s /q dist
13
+ echo [OK] Removed dist\
14
+ )
15
+
16
+ if exist "apps\web\dist" (
17
+ rmdir /s /q apps\web\dist
18
+ echo [OK] Removed apps\web\dist\
19
+ )
20
+
21
+ if exist "apps\server\tmp" (
22
+ rmdir /s /q apps\server\tmp
23
+ echo [OK] Removed apps\server\tmp\
24
+ )
25
+
26
+ if exist "apps\server\internal\frontend\dist" (
27
+ for /f "delims=" %%i in ('dir /b /a-d "apps\server\internal\frontend\dist\*" 2^>nul ^| findstr /v "^\.gitkeep$"') do del /q "apps\server\internal\frontend\dist\%%i" 2>nul
28
+ for /d %%i in ("apps\server\internal\frontend\dist\*") do rd /s /q "%%i" 2>nul
29
+ echo [OK] Cleaned apps\server\internal\frontend\dist\
30
+ )
31
+
32
+ echo.
33
+ echo ========================================
34
+ echo Clean completed!
35
+ echo ========================================
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ const { spawn } = require('child_process')
3
+ const path = require('path')
4
+ const os = require('os')
5
+
6
+ const scriptsDir = __dirname
7
+ const isWindows = os.platform() === 'win32'
8
+ const script = isWindows
9
+ ? path.join(scriptsDir, 'clean.bat')
10
+ : path.join(scriptsDir, 'clean.sh')
11
+
12
+ const child = spawn(script, [], {
13
+ stdio: 'inherit',
14
+ shell: true,
15
+ cwd: path.join(scriptsDir, '..'),
16
+ })
17
+
18
+ child.on('error', (err) => {
19
+ console.error('Failed to start clean:', err)
20
+ process.exit(1)
21
+ })
22
+
23
+ child.on('exit', (code) => {
24
+ process.exit(code || 0)
25
+ })
@@ -0,0 +1,34 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "========================================"
5
+ echo " Keystone Clean"
6
+ echo "========================================"
7
+ echo ""
8
+
9
+ echo "Cleaning build artifacts..."
10
+
11
+ if [ -d "dist" ]; then
12
+ rm -rf dist
13
+ echo "[OK] Removed dist/"
14
+ fi
15
+
16
+ if [ -d "apps/web/dist" ]; then
17
+ rm -rf apps/web/dist
18
+ echo "[OK] Removed apps/web/dist/"
19
+ fi
20
+
21
+ if [ -d "apps/server/tmp" ]; then
22
+ rm -rf apps/server/tmp
23
+ echo "[OK] Removed apps/server/tmp/"
24
+ fi
25
+
26
+ if [ -d "apps/server/internal/frontend/dist" ]; then
27
+ find "apps/server/internal/frontend/dist" -mindepth 1 ! -name '.gitkeep' -delete 2>/dev/null || true
28
+ echo "[OK] Cleaned apps/server/internal/frontend/dist/"
29
+ fi
30
+
31
+ echo ""
32
+ echo "========================================"
33
+ echo " Clean completed!"
34
+ echo "========================================"
@@ -0,0 +1,82 @@
1
+ @echo off
2
+ setlocal enabledelayedexpansion
3
+
4
+ echo ========================================
5
+ echo Keystone Development Server
6
+ echo ========================================
7
+ echo.
8
+
9
+ REM Check prerequisites
10
+ echo Checking prerequisites...
11
+
12
+ REM Check Node.js
13
+ where node >nul 2>&1
14
+ if errorlevel 1 (
15
+ echo [ERROR] Node.js is not installed. Please install Node.js 18+
16
+ exit /b 1
17
+ )
18
+ for /f "tokens=*" %%i in ('node --version') do set NODE_VERSION=%%i
19
+ echo [OK] Node.js %NODE_VERSION%
20
+
21
+ REM Check pnpm
22
+ where pnpm >nul 2>&1
23
+ if errorlevel 1 (
24
+ echo [ERROR] pnpm is not installed. Please install pnpm 8+
25
+ echo Run: npm install -g pnpm
26
+ exit /b 1
27
+ )
28
+ for /f "tokens=*" %%i in ('pnpm --version') do set PNPM_VERSION=%%i
29
+ echo [OK] pnpm %PNPM_VERSION%
30
+
31
+ REM Check Go
32
+ where go >nul 2>&1
33
+ if errorlevel 1 (
34
+ echo [ERROR] Go is not installed. Please install Go 1.24+
35
+ exit /b 1
36
+ )
37
+ for /f "tokens=3" %%i in ('go version') do set GO_VERSION=%%i
38
+ echo [OK] Go %GO_VERSION%
39
+
40
+ REM Check Air
41
+ where air >nul 2>&1
42
+ if errorlevel 1 (
43
+ echo [WARN] Air is not installed. Installing...
44
+ go install github.com/air-verse/air@latest
45
+ )
46
+ echo [OK] Air installed
47
+
48
+ echo.
49
+ echo Prerequisites check passed!
50
+ echo.
51
+
52
+ REM Create data directories for SQLite (root + apps/server)
53
+ if not exist "apps\\server\\data" mkdir apps\\server\\data
54
+ if not exist "apps\\server\\storage" mkdir apps\\server\\storage
55
+
56
+ REM Copy config if not exists
57
+ if not exist "apps\\server\\config.yaml" (
58
+ if exist "apps\\server\\config.example.yaml" (
59
+ copy "apps\\server\\config.example.yaml" "apps\\server\\config.yaml"
60
+ echo [INFO] Created apps\\server\\config.yaml from template
61
+ )
62
+ )
63
+
64
+ echo Starting development servers...
65
+ echo.
66
+ echo Frontend: http://localhost:3000
67
+ echo Backend: http://localhost:8080
68
+ echo API Docs: http://localhost:8080/api/docs/index.html
69
+ echo.
70
+ echo Press Ctrl+C to stop
71
+ echo ========================================
72
+ echo.
73
+
74
+ REM Start backend with Air in a new window
75
+ start "Keystone Backend" cmd /c "cd apps\server && air"
76
+
77
+ REM Wait a moment for backend to start
78
+ timeout /t 2 /nobreak >nul
79
+
80
+ REM Start frontend in current window
81
+ cd apps\web
82
+ pnpm dev
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ const { spawn } = require('child_process')
3
+ const path = require('path')
4
+ const os = require('os')
5
+
6
+ const scriptsDir = __dirname
7
+ const isWindows = os.platform() === 'win32'
8
+ const script = isWindows
9
+ ? path.join(scriptsDir, 'dev.bat')
10
+ : path.join(scriptsDir, 'dev.sh')
11
+
12
+ const child = spawn(script, [], {
13
+ stdio: 'inherit',
14
+ shell: true,
15
+ cwd: path.join(scriptsDir, '..'),
16
+ })
17
+
18
+ child.on('error', (err) => {
19
+ console.error('Failed to start dev servers:', err)
20
+ process.exit(1)
21
+ })
22
+
23
+ child.on('exit', (code) => {
24
+ process.exit(code || 0)
25
+ })
@@ -0,0 +1,88 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "========================================"
5
+ echo " Keystone Development Server"
6
+ echo "========================================"
7
+ echo ""
8
+
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ NC='\033[0m'
13
+
14
+ echo "Checking prerequisites..."
15
+
16
+ if ! command -v node &> /dev/null; then
17
+ echo -e "${RED}[ERROR]${NC} Node.js is not installed. Please install Node.js 18+"
18
+ exit 1
19
+ fi
20
+ NODE_VERSION=$(node --version)
21
+ echo -e "${GREEN}[OK]${NC} Node.js $NODE_VERSION"
22
+
23
+ if ! command -v pnpm &> /dev/null; then
24
+ echo -e "${RED}[ERROR]${NC} pnpm is not installed. Please install pnpm 8+"
25
+ echo "Run: npm install -g pnpm"
26
+ exit 1
27
+ fi
28
+ PNPM_VERSION=$(pnpm --version)
29
+ echo -e "${GREEN}[OK]${NC} pnpm $PNPM_VERSION"
30
+
31
+ if ! command -v go &> /dev/null; then
32
+ echo -e "${RED}[ERROR]${NC} Go is not installed. Please install Go 1.24+"
33
+ exit 1
34
+ fi
35
+ GO_VERSION=$(go version | awk '{print $3}')
36
+ echo -e "${GREEN}[OK]${NC} Go $GO_VERSION"
37
+
38
+ if ! command -v air &> /dev/null; then
39
+ echo -e "${YELLOW}[WARN]${NC} Air is not installed. Installing..."
40
+ go install github.com/air-verse/air@latest
41
+ fi
42
+ echo -e "${GREEN}[OK]${NC} Air installed"
43
+
44
+ echo ""
45
+ echo "Prerequisites check passed!"
46
+ echo ""
47
+
48
+ mkdir -p apps/server/data
49
+ mkdir -p apps/server/storage
50
+
51
+ if [ ! -f "apps/server/config.yaml" ] && [ -f "apps/server/config.example.yaml" ]; then
52
+ cp apps/server/config.example.yaml apps/server/config.yaml
53
+ echo -e "${GREEN}[INFO]${NC} Created apps/server/config.yaml from template"
54
+ fi
55
+
56
+ echo "Starting development servers..."
57
+ echo ""
58
+ echo "Frontend: http://localhost:3000"
59
+ echo "Backend: http://localhost:8080"
60
+ echo "API Docs: http://localhost:8080/api/docs/index.html"
61
+ echo ""
62
+ echo "Press Ctrl+C to stop"
63
+ echo "========================================"
64
+ echo ""
65
+
66
+ cleanup() {
67
+ echo ""
68
+ echo "Stopping development servers..."
69
+ kill $BACKEND_PID 2>/dev/null || true
70
+ kill $FRONTEND_PID 2>/dev/null || true
71
+ exit 0
72
+ }
73
+
74
+ trap cleanup SIGINT SIGTERM
75
+
76
+ cd apps/server
77
+ air &
78
+ BACKEND_PID=$!
79
+ cd ../..
80
+
81
+ sleep 2
82
+
83
+ cd apps/web
84
+ pnpm dev &
85
+ FRONTEND_PID=$!
86
+ cd ../..
87
+
88
+ wait $BACKEND_PID $FRONTEND_PID
@@ -0,0 +1,86 @@
1
+ @echo off
2
+ setlocal enabledelayedexpansion
3
+
4
+ echo ========================================
5
+ echo Keystone Test Runner
6
+ echo ========================================
7
+ echo.
8
+
9
+ echo Checking prerequisites...
10
+ where node >nul 2>&1
11
+ if errorlevel 1 (
12
+ echo [ERROR] Node.js is not installed
13
+ exit /b 1
14
+ )
15
+ echo [OK] Node.js found
16
+
17
+ where go >nul 2>&1
18
+ if errorlevel 1 (
19
+ echo [ERROR] Go is not installed
20
+ exit /b 1
21
+ )
22
+ echo [OK] Go found
23
+
24
+ echo.
25
+ echo Running tests...
26
+ echo.
27
+
28
+ set FAILED=0
29
+
30
+ echo ----------------------------------------
31
+ echo Frontend Tests
32
+ echo ----------------------------------------
33
+ cd apps\web
34
+ call pnpm typecheck
35
+ if errorlevel 1 (
36
+ echo [FAIL] Frontend typecheck failed
37
+ set FAILED=1
38
+ ) else (
39
+ echo [OK] Frontend typecheck passed
40
+ )
41
+ call pnpm lint
42
+ if errorlevel 1 (
43
+ echo [FAIL] Frontend lint failed
44
+ set FAILED=1
45
+ ) else (
46
+ echo [OK] Frontend lint passed
47
+ )
48
+ call pnpm test
49
+ if errorlevel 1 (
50
+ echo [FAIL] Frontend tests failed
51
+ set FAILED=1
52
+ ) else (
53
+ echo [OK] Frontend tests passed
54
+ )
55
+ cd ..\..
56
+
57
+ echo.
58
+ echo ----------------------------------------
59
+ echo Backend Tests
60
+ echo ----------------------------------------
61
+ cd apps\server
62
+ go vet ./...
63
+ if errorlevel 1 (
64
+ echo [FAIL] Backend vet failed
65
+ set FAILED=1
66
+ ) else (
67
+ echo [OK] Backend vet passed
68
+ )
69
+ go test ./... -v
70
+ if errorlevel 1 (
71
+ echo [FAIL] Backend tests failed
72
+ set FAILED=1
73
+ ) else (
74
+ echo [OK] Backend tests passed
75
+ )
76
+ cd ..\..
77
+
78
+ echo.
79
+ echo ========================================
80
+ if %FAILED%==1 (
81
+ echo Tests FAILED
82
+ exit /b 1
83
+ ) else (
84
+ echo All tests PASSED
85
+ )
86
+ echo ========================================
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ const { spawn } = require('child_process')
3
+ const path = require('path')
4
+ const os = require('os')
5
+
6
+ const scriptsDir = __dirname
7
+ const isWindows = os.platform() === 'win32'
8
+ const script = isWindows
9
+ ? path.join(scriptsDir, 'test.bat')
10
+ : path.join(scriptsDir, 'test.sh')
11
+
12
+ const child = spawn(script, [], {
13
+ stdio: 'inherit',
14
+ shell: true,
15
+ cwd: path.join(scriptsDir, '..'),
16
+ })
17
+
18
+ child.on('error', (err) => {
19
+ console.error('Failed to start tests:', err)
20
+ process.exit(1)
21
+ })
22
+
23
+ child.on('exit', (code) => {
24
+ process.exit(code || 0)
25
+ })