create-entity-server 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/bin/create.js +280 -0
  2. package/package.json +42 -0
  3. package/template/.env.example +14 -0
  4. package/template/configs/cache.json +22 -0
  5. package/template/configs/cors.json +7 -0
  6. package/template/configs/database.json +23 -0
  7. package/template/configs/jwt.json +7 -0
  8. package/template/configs/logging.json +45 -0
  9. package/template/configs/security.json +21 -0
  10. package/template/configs/server.json +10 -0
  11. package/template/entities/Account/account_audit.json +17 -0
  12. package/template/entities/Auth/account.json +60 -0
  13. package/template/entities/Auth/api_keys.json +26 -0
  14. package/template/entities/Auth/license.json +36 -0
  15. package/template/entities/Auth/rbac_roles.json +76 -0
  16. package/template/entities/README.md +380 -0
  17. package/template/entities/System/system_audit_log.json +65 -0
  18. package/template/entities/company.json +22 -0
  19. package/template/entities/product.json +36 -0
  20. package/template/entities/todo.json +16 -0
  21. package/template/samples/README.md +65 -0
  22. package/template/samples/flutter/lib/entity_server_client.dart +218 -0
  23. package/template/samples/flutter/pubspec.yaml +14 -0
  24. package/template/samples/java/EntityServerClient.java +304 -0
  25. package/template/samples/java/EntityServerExample.java +49 -0
  26. package/template/samples/kotlin/EntityServerClient.kt +194 -0
  27. package/template/samples/node/package.json +16 -0
  28. package/template/samples/node/src/EntityServerClient.js +246 -0
  29. package/template/samples/node/src/example.js +39 -0
  30. package/template/samples/php/ci4/Controllers/ProductController.php +141 -0
  31. package/template/samples/php/ci4/Libraries/EntityServer.php +260 -0
  32. package/template/samples/php/laravel/Http/Controllers/ProductController.php +62 -0
  33. package/template/samples/php/laravel/Services/EntityServerService.php +210 -0
  34. package/template/samples/python/entity_server.py +225 -0
  35. package/template/samples/python/example.py +50 -0
  36. package/template/samples/react/src/api/entityServerClient.ts +290 -0
  37. package/template/samples/react/src/example.tsx +127 -0
  38. package/template/samples/react/src/hooks/useEntity.ts +105 -0
  39. package/template/samples/swift/EntityServerClient.swift +221 -0
  40. package/template/scripts/api-key.ps1 +123 -0
  41. package/template/scripts/api-key.sh +130 -0
  42. package/template/scripts/cleanup-history.ps1 +69 -0
  43. package/template/scripts/cleanup-history.sh +54 -0
  44. package/template/scripts/cli.ps1 +24 -0
  45. package/template/scripts/cli.sh +27 -0
  46. package/template/scripts/entity.ps1 +70 -0
  47. package/template/scripts/entity.sh +72 -0
  48. package/template/scripts/generate-env-keys.ps1 +125 -0
  49. package/template/scripts/generate-env-keys.sh +148 -0
  50. package/template/scripts/install-systemd.sh +222 -0
  51. package/template/scripts/normalize-entities.ps1 +87 -0
  52. package/template/scripts/normalize-entities.sh +132 -0
  53. package/template/scripts/rbac-role.ps1 +124 -0
  54. package/template/scripts/rbac-role.sh +127 -0
  55. package/template/scripts/remove-systemd.sh +158 -0
  56. package/template/scripts/reset-all.ps1 +83 -0
  57. package/template/scripts/reset-all.sh +95 -0
  58. package/template/scripts/run.ps1 +239 -0
  59. package/template/scripts/run.sh +315 -0
  60. package/template/scripts/sync.ps1 +145 -0
  61. package/template/scripts/sync.sh +178 -0
  62. package/template/scripts/update-server.ps1 +117 -0
  63. package/template/scripts/update-server.sh +165 -0
@@ -0,0 +1,54 @@
1
+ #!/bin/bash
2
+
3
+ # Cleanup expired history rows by history_ttl
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
7
+
8
+ cd "$PROJECT_ROOT"
9
+
10
+ # Load language from .env
11
+ if [ -f .env ]; then
12
+ LANGUAGE=$(grep '^LANGUAGE=' .env | cut -d '=' -f2)
13
+ fi
14
+ LANGUAGE=${LANGUAGE:-ko}
15
+
16
+ show_help() {
17
+ if [ "$LANGUAGE" = "en" ]; then
18
+ echo "History TTL Cleanup"
19
+ echo "==================="
20
+ echo ""
21
+ echo "Usage: $0 [--entity=<name>] [--apply]"
22
+ echo ""
23
+ echo "Options:"
24
+ echo " --entity=<name> Cleanup only one entity history"
25
+ echo " --apply Execute delete (default: dry-run)"
26
+ else
27
+ echo "히스토리 TTL 정리"
28
+ echo "================"
29
+ echo ""
30
+ echo "사용법: $0 [--entity=<name>] [--apply]"
31
+ echo ""
32
+ echo "옵션:"
33
+ echo " --entity=<name> 특정 엔티티 히스토리만 정리"
34
+ echo " --apply 실제 삭제 실행 (기본: dry-run)"
35
+ fi
36
+ }
37
+
38
+ if [ $# -eq 0 ]; then
39
+ show_help
40
+ exit 0
41
+ fi
42
+
43
+ # Require prebuilt CLI binary
44
+ if [ ! -f "$PROJECT_ROOT/bin/entity-cli" ]; then
45
+ if [ "$LANGUAGE" = "en" ]; then
46
+ echo "❌ bin/entity-cli not found"
47
+ else
48
+ echo "❌ bin/entity-cli 파일이 없습니다"
49
+ fi
50
+ exit 1
51
+ fi
52
+
53
+ # Pass-through to CLI
54
+ "$PROJECT_ROOT/bin/entity-cli" cleanup-history "$@"
@@ -0,0 +1,24 @@
1
+ # Entity CLI wrapper script (Windows PowerShell)
2
+
3
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
4
+ $ProjectRoot = Split-Path -Parent $ScriptDir
5
+ $BinPath = Join-Path $ProjectRoot "bin\entity-cli.exe"
6
+
7
+ # Load language from .env
8
+ $Language = "ko"
9
+ $EnvFile = Join-Path $ProjectRoot ".env"
10
+ if (Test-Path $EnvFile) {
11
+ $LangLine = Get-Content $EnvFile | Where-Object { $_ -match '^LANGUAGE=' } | Select-Object -First 1
12
+ if ($LangLine) { $Language = $LangLine -replace '^LANGUAGE=', '' }
13
+ }
14
+
15
+ # Require prebuilt CLI binary
16
+ if (-not (Test-Path $BinPath)) {
17
+ if ($Language -eq "en") { Write-Host "X bin/entity-cli.exe not found" }
18
+ else { Write-Host "X bin/entity-cli.exe 파일이 없습니다" }
19
+ exit 1
20
+ }
21
+
22
+ Set-Location $ProjectRoot
23
+ $env:ENTITY_CLI_NAME = "cli"
24
+ & $BinPath @args
@@ -0,0 +1,27 @@
1
+ #!/bin/bash
2
+
3
+ # Entity CLI wrapper script
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
7
+ BIN_PATH="$PROJECT_ROOT/bin/entity-cli"
8
+
9
+ # Load language from .env
10
+ if [ -f "$PROJECT_ROOT/.env" ]; then
11
+ LANGUAGE=$(grep '^LANGUAGE=' "$PROJECT_ROOT/.env" | cut -d '=' -f2)
12
+ fi
13
+ LANGUAGE=${LANGUAGE:-ko}
14
+
15
+ # Require prebuilt CLI binary
16
+ if [ ! -f "$BIN_PATH" ]; then
17
+ if [ "$LANGUAGE" = "en" ]; then
18
+ echo "❌ bin/entity-cli not found"
19
+ else
20
+ echo "❌ bin/entity-cli 파일이 없습니다"
21
+ fi
22
+ exit 1
23
+ fi
24
+
25
+ # Run the CLI tool
26
+ cd "$PROJECT_ROOT"
27
+ ENTITY_CLI_NAME="cli" "$BIN_PATH" "$@"
@@ -0,0 +1,70 @@
1
+ # Init Entity Tables - Windows PowerShell
2
+ # Add, reset, or truncate one entity's data/index/history tables
3
+
4
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
5
+ $ProjectRoot = Split-Path -Parent $ScriptDir
6
+
7
+ Set-Location $ProjectRoot
8
+
9
+ # Load language from .env
10
+ $Language = "ko"
11
+ $EnvFile = Join-Path $ProjectRoot ".env"
12
+ if (Test-Path $EnvFile) {
13
+ $LangLine = Get-Content $EnvFile | Where-Object { $_ -match '^LANGUAGE=' } | Select-Object -First 1
14
+ if ($LangLine) { $Language = $LangLine -replace '^LANGUAGE=', '' }
15
+ }
16
+
17
+ function Show-Help {
18
+ if ($Language -eq "en") {
19
+ Write-Host "Init Entity Tables"
20
+ Write-Host "=================="
21
+ Write-Host ""
22
+ Write-Host "Add, reset, or truncate one entity's data/index/history tables."
23
+ Write-Host ""
24
+ Write-Host "Usage: .\entity.ps1 --entity=<name> [--reset|--truncate] [--apply]"
25
+ Write-Host ""
26
+ Write-Host "Options:"
27
+ Write-Host " --entity=<name> Entity name (required)"
28
+ Write-Host " --reset Drop this entity tables and recreate"
29
+ Write-Host " --truncate Delete all rows and reset AUTO_INCREMENT=1"
30
+ Write-Host " --apply Execute (default is dry-run)"
31
+ Write-Host ""
32
+ Write-Host "Examples:"
33
+ Write-Host " .\entity.ps1 --entity=license --apply"
34
+ Write-Host " .\entity.ps1 --entity=account --reset --apply"
35
+ Write-Host " .\entity.ps1 --entity=account --truncate --apply"
36
+ } else {
37
+ Write-Host "단일 엔티티 테이블 초기화"
38
+ Write-Host "====================="
39
+ Write-Host ""
40
+ Write-Host "하나의 엔티티(data/index/history) 테이블을 추가/재생성/비우기(truncate) 합니다."
41
+ Write-Host ""
42
+ Write-Host "사용법: .\entity.ps1 --entity=<name> [--reset|--truncate] [--apply]"
43
+ Write-Host ""
44
+ Write-Host "옵션:"
45
+ Write-Host " --entity=<name> 엔티티명 (필수)"
46
+ Write-Host " --reset 해당 엔티티 테이블 드롭 후 재생성"
47
+ Write-Host " --truncate 데이터 전체 삭제 + AUTO_INCREMENT=1 초기화"
48
+ Write-Host " --apply 실제 실행 (기본은 dry-run)"
49
+ Write-Host ""
50
+ Write-Host "예제:"
51
+ Write-Host " .\entity.ps1 --entity=license --apply"
52
+ Write-Host " .\entity.ps1 --entity=account --reset --apply"
53
+ Write-Host " .\entity.ps1 --entity=account --truncate --apply"
54
+ }
55
+ }
56
+
57
+ if ($args.Count -eq 0) {
58
+ Show-Help
59
+ exit 0
60
+ }
61
+
62
+ $CliBin = Join-Path $ProjectRoot "bin\entity-cli.exe"
63
+ if (-not (Test-Path $CliBin)) {
64
+ if ($Language -eq "en") { Write-Host "X bin/entity-cli.exe not found" }
65
+ else { Write-Host "X bin/entity-cli.exe 파일이 없습니다" }
66
+ exit 1
67
+ }
68
+
69
+ # Pass-through to CLI
70
+ & $CliBin init-entity @args
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+
3
+ # Add or reset a single entity tables
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
7
+
8
+ cd "$PROJECT_ROOT"
9
+
10
+ # Load language from .env
11
+ if [ -f .env ]; then
12
+ LANGUAGE=$(grep '^LANGUAGE=' .env | cut -d '=' -f2)
13
+ fi
14
+ LANGUAGE=${LANGUAGE:-ko}
15
+
16
+ show_help() {
17
+ if [ "$LANGUAGE" = "en" ]; then
18
+ echo "Init Entity Tables"
19
+ echo "=================="
20
+ echo ""
21
+ echo "Add, reset, or truncate one entity's data/index/history tables."
22
+ echo ""
23
+ echo "Usage: $0 --entity=<name> [--reset|--truncate] [--apply]"
24
+ echo ""
25
+ echo "Options:"
26
+ echo " --entity=<name> Entity name (required)"
27
+ echo " --reset Drop this entity tables and recreate"
28
+ echo " --truncate Delete all rows and reset AUTO_INCREMENT=1"
29
+ echo " --apply Execute (default is dry-run)"
30
+ echo ""
31
+ echo "Examples:"
32
+ echo " $0 --entity=license --apply"
33
+ echo " $0 --entity=account --reset --apply"
34
+ echo " $0 --entity=account --truncate --apply"
35
+ else
36
+ echo "단일 엔티티 테이블 초기화"
37
+ echo "====================="
38
+ echo ""
39
+ echo "하나의 엔티티(data/index/history) 테이블을 추가/재생성/비우기(truncate) 합니다."
40
+ echo ""
41
+ echo "사용법: $0 --entity=<name> [--reset|--truncate] [--apply]"
42
+ echo ""
43
+ echo "옵션:"
44
+ echo " --entity=<name> 엔티티명 (필수)"
45
+ echo " --reset 해당 엔티티 테이블 드롭 후 재생성"
46
+ echo " --truncate 데이터 전체 삭제 + AUTO_INCREMENT=1 초기화"
47
+ echo " --apply 실제 실행 (기본은 dry-run)"
48
+ echo ""
49
+ echo "예제:"
50
+ echo " $0 --entity=license --apply"
51
+ echo " $0 --entity=account --reset --apply"
52
+ echo " $0 --entity=account --truncate --apply"
53
+ fi
54
+ }
55
+
56
+ if [ $# -eq 0 ]; then
57
+ show_help
58
+ exit 0
59
+ fi
60
+
61
+ # Require prebuilt CLI binary
62
+ if [ ! -f "$PROJECT_ROOT/bin/entity-cli" ]; then
63
+ if [ "$LANGUAGE" = "en" ]; then
64
+ echo "❌ bin/entity-cli not found"
65
+ else
66
+ echo "❌ bin/entity-cli 파일이 없습니다"
67
+ fi
68
+ exit 1
69
+ fi
70
+
71
+ # Pass-through to CLI
72
+ "$PROJECT_ROOT/bin/entity-cli" init-entity "$@"
@@ -0,0 +1,125 @@
1
+ # Generate Environment Keys/Secrets - Windows PowerShell
2
+ # Generates ENCRYPTION_KEY and JWT_SECRET random values
3
+ param(
4
+ [switch]$Create,
5
+ [switch]$Export,
6
+ [switch]$Apply
7
+ )
8
+
9
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
10
+ $ProjectRoot = Split-Path -Parent $ScriptDir
11
+
12
+ # Load language from .env (env var takes priority)
13
+ $Language = $env:LANGUAGE
14
+ if (-not $Language) {
15
+ $EnvFile = Join-Path $ProjectRoot ".env"
16
+ if (Test-Path $EnvFile) {
17
+ $LangLine = Get-Content $EnvFile | Where-Object { $_ -match '^LANGUAGE=' } | Select-Object -Last 1
18
+ if ($LangLine) { $Language = $LangLine -replace '^LANGUAGE=', '' }
19
+ }
20
+ }
21
+ if (-not $Language) { $Language = "ko" }
22
+
23
+ function Show-Help {
24
+ if ($Language -eq "en") {
25
+ Write-Host "Generate Environment Keys/Secrets"
26
+ Write-Host "==================================="
27
+ Write-Host ""
28
+ Write-Host "Generates random values for ENCRYPTION_KEY and JWT_SECRET."
29
+ Write-Host ""
30
+ Write-Host "Note: API keys (api_keys entity) are managed via DB commands:"
31
+ Write-Host " .\scripts\api-key.ps1 add --role=admin --apply"
32
+ Write-Host ""
33
+ Write-Host "Usage: .\generate-env-keys.ps1 [-Create|-Export|-Apply]"
34
+ Write-Host ""
35
+ Write-Host "Options:"
36
+ Write-Host " -Create Print copy/paste format for .env"
37
+ Write-Host " -Export Print shell export format"
38
+ Write-Host " -Apply Apply values directly to project .env"
39
+ Write-Host ""
40
+ Write-Host "Examples:"
41
+ Write-Host " .\generate-env-keys.ps1 -Create"
42
+ Write-Host " .\generate-env-keys.ps1 -Export"
43
+ Write-Host " .\generate-env-keys.ps1 -Apply"
44
+ } else {
45
+ Write-Host "환경 변수 키/시크릿 생성"
46
+ Write-Host "======================="
47
+ Write-Host ""
48
+ Write-Host "ENCRYPTION_KEY, JWT_SECRET 랜덤 값을 생성합니다."
49
+ Write-Host ""
50
+ Write-Host "참고: API 키(api_keys 엔티티)는 DB 명령으로 관리합니다:"
51
+ Write-Host " .\scripts\api-key.ps1 add --role=admin --apply"
52
+ Write-Host ""
53
+ Write-Host "사용법: .\generate-env-keys.ps1 [-Create|-Export|-Apply]"
54
+ Write-Host ""
55
+ Write-Host "옵션:"
56
+ Write-Host " -Create .env 복붙 형식으로 출력"
57
+ Write-Host " -Export export 형식으로 출력"
58
+ Write-Host " -Apply 프로젝트 루트 .env 파일에 즉시 반영"
59
+ Write-Host ""
60
+ Write-Host "예제:"
61
+ Write-Host " .\generate-env-keys.ps1 -Create"
62
+ Write-Host " .\generate-env-keys.ps1 -Export"
63
+ Write-Host " .\generate-env-keys.ps1 -Apply"
64
+ }
65
+ }
66
+
67
+ if (-not $Create -and -not $Export -and -not $Apply) {
68
+ Show-Help
69
+ exit 0
70
+ }
71
+
72
+ function New-RandomHex {
73
+ param([int]$Bytes)
74
+ $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
75
+ $buf = New-Object byte[] $Bytes
76
+ $rng.GetBytes($buf)
77
+ return ($buf | ForEach-Object { $_.ToString("x2") }) -join ""
78
+ }
79
+
80
+ $EncryptionKey = New-RandomHex 16
81
+ $JwtSecret = New-RandomHex 32
82
+
83
+ if ($Export) {
84
+ Write-Host "SET ENCRYPTION_KEY=$EncryptionKey"
85
+ Write-Host "SET JWT_SECRET=$JwtSecret"
86
+ Write-Host ""
87
+ Write-Host "# PowerShell:"
88
+ Write-Host "`$env:ENCRYPTION_KEY=`"$EncryptionKey`""
89
+ Write-Host "`$env:JWT_SECRET=`"$JwtSecret`""
90
+ } elseif ($Create) {
91
+ if ($Language -eq "en") { Write-Host "# Copy & paste to .env" }
92
+ else { Write-Host "# .env에 복사해서 붙여넣기" }
93
+ Write-Host "ENCRYPTION_KEY=$EncryptionKey"
94
+ Write-Host "JWT_SECRET=$JwtSecret"
95
+ } elseif ($Apply) {
96
+ $EnvFile = Join-Path $ProjectRoot ".env"
97
+ if (-not (Test-Path $EnvFile)) { New-Item -ItemType File -Path $EnvFile | Out-Null }
98
+
99
+ function Update-EnvKey {
100
+ param([string]$File, [string]$Key, [string]$Value)
101
+ $content = Get-Content $File
102
+ $found = $false
103
+ $newContent = $content | ForEach-Object {
104
+ if ($_ -match "^$Key=") {
105
+ $found = $true
106
+ "$Key=$Value"
107
+ } else { $_ }
108
+ }
109
+ if (-not $found) { $newContent += "$Key=$Value" }
110
+ $newContent | Set-Content $File
111
+ }
112
+
113
+ Update-EnvKey $EnvFile "ENCRYPTION_KEY" $EncryptionKey
114
+ Update-EnvKey $EnvFile "JWT_SECRET" $JwtSecret
115
+
116
+ if ($Language -eq "en") {
117
+ Write-Host "OK Updated: $EnvFile"
118
+ Write-Host " - ENCRYPTION_KEY"
119
+ Write-Host " - JWT_SECRET"
120
+ } else {
121
+ Write-Host "OK 업데이트 완료: $EnvFile"
122
+ Write-Host " - ENCRYPTION_KEY"
123
+ Write-Host " - JWT_SECRET"
124
+ }
125
+ }
@@ -0,0 +1,148 @@
1
+ #!/bin/bash
2
+ # 환경 변수 키/시크릿 생성 스크립트
3
+ # ENCRYPTION_KEY, JWT_SECRET 랜덤 값 생성
4
+
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
9
+
10
+ # LANGUAGE 환경변수를 우선 사용하고, 없으면 .env에서 로드
11
+ if [ -z "${LANGUAGE:-}" ] && [ -f "$PROJECT_ROOT/.env" ]; then
12
+ LANGUAGE=$(grep '^LANGUAGE=' "$PROJECT_ROOT/.env" | tail -n 1 | cut -d '=' -f2 || true)
13
+ fi
14
+ LANGUAGE=${LANGUAGE:-ko}
15
+
16
+ show_help() {
17
+ if [ "$LANGUAGE" = "en" ]; then
18
+ cat <<'EOF'
19
+ Generate Environment Keys/Secrets
20
+ ===================================
21
+
22
+ Generates random values for ENCRYPTION_KEY and JWT_SECRET.
23
+
24
+ Note: API keys (api_keys entity) are managed via DB commands:
25
+ ./scripts/api-key.sh add --role=admin --apply
26
+
27
+ Usage: ./scripts/generate-env-keys.sh [--create|--export|--apply]
28
+
29
+ Options:
30
+ --create Print copy/paste format for .env
31
+ --export Print shell export format
32
+ --apply Apply values directly to project .env
33
+
34
+ Examples:
35
+ ./scripts/generate-env-keys.sh --create
36
+ ./scripts/generate-env-keys.sh --export
37
+ ./scripts/generate-env-keys.sh --apply
38
+ EOF
39
+ else
40
+ cat <<'EOF'
41
+ 환경 변수 키/시크릿 생성
42
+ =======================
43
+
44
+ ENCRYPTION_KEY, JWT_SECRET 랜덤 값을 생성합니다.
45
+
46
+ 참고: API 키(api_keys 엔티티)는 DB 명령으로 관리합니다:
47
+ ./scripts/api-key.sh add --role=admin --apply
48
+
49
+ 사용법: ./scripts/generate-env-keys.sh [--create|--export|--apply]
50
+
51
+ 옵션:
52
+ --create .env 복붙 형식으로 출력
53
+ --export export 형식으로 출력
54
+ --apply 프로젝트 루트 .env 파일에 즉시 반영
55
+
56
+ 예제:
57
+ ./scripts/generate-env-keys.sh --create
58
+ ./scripts/generate-env-keys.sh --export
59
+ ./scripts/generate-env-keys.sh --apply
60
+ EOF
61
+ fi
62
+ }
63
+
64
+ if [[ $# -eq 0 ]]; then
65
+ show_help
66
+ exit 0
67
+ fi
68
+
69
+ OUTPUT_MODE=""
70
+
71
+ while [[ $# -gt 0 ]]; do
72
+ case "$1" in
73
+ --create)
74
+ OUTPUT_MODE="dotenv"
75
+ shift
76
+ ;;
77
+ --export)
78
+ OUTPUT_MODE="export"
79
+ shift
80
+ ;;
81
+ --apply)
82
+ OUTPUT_MODE="apply-env"
83
+ shift
84
+ ;;
85
+ *)
86
+ if [ "$LANGUAGE" = "en" ]; then
87
+ echo "❌ Unknown option: $1"
88
+ else
89
+ echo "❌ 알 수 없는 옵션: $1"
90
+ fi
91
+ echo ""
92
+ show_help
93
+ exit 1
94
+ ;;
95
+ esac
96
+ done
97
+
98
+ gen_hex() {
99
+ local bytes="$1"
100
+ if command -v openssl >/dev/null 2>&1; then
101
+ openssl rand -hex "$bytes"
102
+ else
103
+ head -c "$bytes" /dev/urandom | od -An -tx1 | tr -d ' \n'
104
+ fi
105
+ }
106
+
107
+ ENCRYPTION_KEY="$(gen_hex 16)"
108
+ JWT_SECRET="$(gen_hex 32)"
109
+
110
+ if [[ "$OUTPUT_MODE" == "export" ]]; then
111
+ cat <<EOF
112
+ export ENCRYPTION_KEY=$ENCRYPTION_KEY
113
+ export JWT_SECRET=$JWT_SECRET
114
+ EOF
115
+ elif [[ "$OUTPUT_MODE" == "dotenv" ]]; then
116
+ cat <<EOF
117
+ # $( [ "$LANGUAGE" = "en" ] && echo "Copy & paste to .env" || echo ".env에 복사해서 붙여넣기" )
118
+ ENCRYPTION_KEY=$ENCRYPTION_KEY
119
+ JWT_SECRET=$JWT_SECRET
120
+ EOF
121
+ else
122
+ # --apply
123
+ ENV_FILE="$PROJECT_ROOT/.env"
124
+ touch "$ENV_FILE"
125
+
126
+ upsert_env_key() {
127
+ local key="$1"
128
+ local value="$2"
129
+ if grep -q "^${key}=" "$ENV_FILE"; then
130
+ sed -i "s|^${key}=.*$|${key}=${value}|" "$ENV_FILE"
131
+ else
132
+ echo "${key}=${value}" >> "$ENV_FILE"
133
+ fi
134
+ }
135
+
136
+ upsert_env_key "ENCRYPTION_KEY" "$ENCRYPTION_KEY"
137
+ upsert_env_key "JWT_SECRET" "$JWT_SECRET"
138
+
139
+ if [ "$LANGUAGE" = "en" ]; then
140
+ echo "✓ Updated: $ENV_FILE"
141
+ echo " - ENCRYPTION_KEY"
142
+ echo " - JWT_SECRET"
143
+ else
144
+ echo "✓ 업데이트 완료: $ENV_FILE"
145
+ echo " - ENCRYPTION_KEY"
146
+ echo " - JWT_SECRET"
147
+ fi
148
+ fi