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,145 @@
1
+ # Sync entity index schema
2
+
3
+ param(
4
+ [string]$Target = "",
5
+ [switch]$Apply,
6
+ [switch]$WithData
7
+ )
8
+
9
+ $ProjectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
10
+ Set-Location $ProjectRoot
11
+
12
+ # Load language from .env
13
+ $Language = "ko"
14
+ if (Test-Path ".env") {
15
+ $EnvLine = Get-Content ".env" | Where-Object { $_ -match '^LANGUAGE=' }
16
+ if ($EnvLine) { $Language = $EnvLine -replace '^LANGUAGE=', '' }
17
+ }
18
+
19
+ # Show usage if no arguments
20
+ if (-not $Target) {
21
+ if ($Language -eq "en") {
22
+ Write-Host "Sync Entity Index Schema"
23
+ Write-Host "========================"
24
+ Write-Host ""
25
+ Write-Host "Synchronize index table schema with entity configuration."
26
+ Write-Host ""
27
+ Write-Host "Usage: .\sync.ps1 <EntityName>|-All [-Apply] [-WithData]"
28
+ Write-Host ""
29
+ Write-Host "Arguments:"
30
+ Write-Host " EntityName Name of the entity to sync (required)"
31
+ Write-Host " -All Sync all entities in entities/"
32
+ Write-Host ""
33
+ Write-Host "Options:"
34
+ Write-Host " -Apply Apply changes to database (default: dry-run)"
35
+ Write-Host " -WithData Sync schema and backfill index rows from existing data"
36
+ Write-Host ""
37
+ Write-Host "Examples:"
38
+ Write-Host " .\sync.ps1 user # Preview changes for user entity"
39
+ Write-Host " .\sync.ps1 user -Apply # Apply changes for user entity"
40
+ Write-Host " .\sync.ps1 user -Apply -WithData # Apply + backfill"
41
+ Write-Host " .\sync.ps1 -All # Preview for all entities"
42
+ Write-Host " .\sync.ps1 -All -Apply # Apply for all entities"
43
+ Write-Host " .\sync.ps1 license -Apply # Sync license entity schema"
44
+ } else {
45
+ Write-Host "엔티티 인덱스 스키마 동기화"
46
+ Write-Host "======================="
47
+ Write-Host ""
48
+ Write-Host "엔티티 설정과 인덱스 테이블 스키마를 동기화합니다."
49
+ Write-Host ""
50
+ Write-Host "사용법: .\sync.ps1 <엔티티명>|-All [-Apply] [-WithData]"
51
+ Write-Host ""
52
+ Write-Host "인자:"
53
+ Write-Host " 엔티티명 동기화할 엔티티 이름 (필수)"
54
+ Write-Host " -All entities/ 내 전체 엔티티 동기화"
55
+ Write-Host ""
56
+ Write-Host "옵션:"
57
+ Write-Host " -Apply 데이터베이스에 변경사항 적용 (기본값: 미리보기)"
58
+ Write-Host " -WithData 스키마 동기화 + 기존 데이터 인덱스 백필"
59
+ Write-Host ""
60
+ Write-Host "예제:"
61
+ Write-Host " .\sync.ps1 user # user 엔티티 변경사항 미리보기"
62
+ Write-Host " .\sync.ps1 user -Apply # user 엔티티 변경사항 적용"
63
+ Write-Host " .\sync.ps1 user -Apply -WithData # 적용 + 기존 데이터 백필"
64
+ Write-Host " .\sync.ps1 -All # 전체 엔티티 미리보기"
65
+ Write-Host " .\sync.ps1 -All -Apply # 전체 엔티티 적용"
66
+ Write-Host " .\sync.ps1 license -Apply # license 엔티티 스키마 동기화"
67
+ }
68
+ exit 0
69
+ }
70
+
71
+ # Validate --with-data requires --apply
72
+ if ($WithData -and -not $Apply) {
73
+ if ($Language -eq "en") {
74
+ Write-Host "❌ -WithData requires -Apply"
75
+ } else {
76
+ Write-Host "❌ -WithData 는 -Apply 와 함께 사용해야 합니다"
77
+ }
78
+ exit 1
79
+ }
80
+
81
+ # Require prebuilt CLI binary
82
+ $CliBin = Join-Path $ProjectRoot "entity-cli.exe"
83
+ if (-not (Test-Path $CliBin)) {
84
+ if ($Language -eq "en") {
85
+ Write-Host "❌ entity-cli.exe not found"
86
+ } else {
87
+ Write-Host "❌ entity-cli.exe 파일이 없습니다"
88
+ }
89
+ exit 1
90
+ }
91
+
92
+ function Invoke-SyncEntity {
93
+ param([string]$EntityName)
94
+ $Args = @("sync-index", "--entity=$EntityName")
95
+ if ($Apply) { $Args += "--apply" }
96
+ if ($WithData) { $Args += "--with-data" }
97
+ Write-Host "[sync] $EntityName"
98
+ & $CliBin @Args
99
+ return $LASTEXITCODE -eq 0
100
+ }
101
+
102
+ if ($Target -eq "-All" -or $Target -eq "--all") {
103
+ $EntityFiles = Get-ChildItem -Path (Join-Path $ProjectRoot "entities") -Filter "*.json" -Recurse |
104
+ Select-Object -ExpandProperty BaseName | Sort-Object -Unique
105
+
106
+ if ($EntityFiles.Count -eq 0) {
107
+ if ($Language -eq "en") {
108
+ Write-Host "❌ No entity config files found in entities/"
109
+ } else {
110
+ Write-Host "❌ entities/ 에 엔티티 설정 파일이 없습니다"
111
+ }
112
+ exit 1
113
+ }
114
+
115
+ $TotalCount = $EntityFiles.Count
116
+ $SuccessCount = 0
117
+ $FailedCount = 0
118
+
119
+ foreach ($Entity in $EntityFiles) {
120
+ if (Invoke-SyncEntity $Entity) {
121
+ $SuccessCount++
122
+ } else {
123
+ $FailedCount++
124
+ }
125
+ }
126
+
127
+ $ApplyLabel = if ($Apply) { "apply" } else { "dry-run" }
128
+ $ModeLabel = if ($WithData) { "with-data" } else { "index-only" }
129
+ Write-Host ""
130
+ Write-Host "[summary] target=all mode=$ModeLabel apply=$ApplyLabel total=$TotalCount success=$SuccessCount failed=$FailedCount"
131
+
132
+ if ($FailedCount -gt 0) { exit 1 }
133
+ } else {
134
+ $ok = Invoke-SyncEntity $Target
135
+ $ApplyLabel = if ($Apply) { "apply" } else { "dry-run" }
136
+ $ModeLabel = if ($WithData) { "with-data" } else { "index-only" }
137
+ if ($ok) {
138
+ Write-Host ""
139
+ Write-Host "[summary] target=$Target mode=$ModeLabel apply=$ApplyLabel total=1 success=1 failed=0"
140
+ } else {
141
+ Write-Host ""
142
+ Write-Host "[summary] target=$Target mode=$ModeLabel apply=$ApplyLabel total=1 success=0 failed=1"
143
+ exit 1
144
+ }
145
+ }
@@ -0,0 +1,178 @@
1
+ #!/bin/bash
2
+
3
+ # Sync entity index schema
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 usage if no arguments
17
+ if [ $# -eq 0 ]; then
18
+ if [ "$LANGUAGE" = "en" ]; then
19
+ echo "Sync Entity Index Schema"
20
+ echo "========================"
21
+ echo ""
22
+ echo "Synchronize index table schema with entity configuration."
23
+ echo ""
24
+ echo "Usage: $0 <entity-name>|--all [--dry-run|--apply] [--index-only|--with-data]"
25
+ echo ""
26
+ echo "Arguments:"
27
+ echo " entity-name Name of the entity to sync (required)"
28
+ echo " --all Sync all entities in entities/"
29
+ echo ""
30
+ echo "Options:"
31
+ echo " --dry-run Preview mode - show what will be changed"
32
+ echo " --apply Apply changes to database"
33
+ echo " --index-only Sync index schema only (default)"
34
+ echo " --with-data Sync schema and backfill index rows from existing data"
35
+ echo ""
36
+ echo "Examples:"
37
+ echo " $0 user --dry-run # Preview changes for user entity"
38
+ echo " $0 user --apply # Apply changes for user entity"
39
+ echo " $0 user --apply --with-data # Apply + backfill"
40
+ echo " $0 --all --dry-run # Preview for all entities"
41
+ echo " $0 --all --apply # Apply for all entities"
42
+ echo " $0 license --apply # Sync license entity schema"
43
+ else
44
+ echo "엔티티 인덱스 스키마 동기화"
45
+ echo "======================="
46
+ echo ""
47
+ echo "엔티티 설정과 인덱스 테이블 스키마를 동기화합니다."
48
+ echo ""
49
+ echo "사용법: $0 <엔티티명>|--all [--dry-run|--apply] [--index-only|--with-data]"
50
+ echo ""
51
+ echo "인자:"
52
+ echo " 엔티티명 동기화할 엔티티 이름 (필수)"
53
+ echo " --all entities/ 내 전체 엔티티 동기화"
54
+ echo ""
55
+ echo "옵션:"
56
+ echo " --dry-run 미리보기 모드 - 변경사항 확인"
57
+ echo " --apply 데이터베이스에 변경사항 적용"
58
+ echo " --index-only 인덱스 스키마만 동기화 (기본값)"
59
+ echo " --with-data 스키마 동기화 + 기존 데이터 인덱스 백필"
60
+ echo ""
61
+ echo "예제:"
62
+ echo " $0 user --dry-run # user 엔티티 변경사항 미리보기"
63
+ echo " $0 user --apply # user 엔티티 변경사항 적용"
64
+ echo " $0 user --apply --with-data # 적용 + 기존 데이터 백필"
65
+ echo " $0 --all --dry-run # 전체 엔티티 미리보기"
66
+ echo " $0 --all --apply # 전체 엔티티 적용"
67
+ echo " $0 license --apply # license 엔티티 스키마 동기화"
68
+ fi
69
+ exit 0
70
+ fi
71
+
72
+ # Require prebuilt CLI binary
73
+ if [ ! -f "$PROJECT_ROOT/bin/entity-cli" ]; then
74
+ if [ "$LANGUAGE" = "en" ]; then
75
+ echo "❌ bin/entity-cli not found"
76
+ else
77
+ echo "❌ bin/entity-cli 파일이 없습니다"
78
+ fi
79
+ exit 1
80
+ fi
81
+
82
+ TARGET="$1"
83
+ APPLY_MODE="--dry-run"
84
+ SYNC_MODE="--index-only"
85
+
86
+ for arg in "${@:2}"; do
87
+ case "$arg" in
88
+ --dry-run|--apply)
89
+ APPLY_MODE="$arg"
90
+ ;;
91
+ --index-only|--with-data)
92
+ SYNC_MODE="$arg"
93
+ ;;
94
+ *)
95
+ if [ "$LANGUAGE" = "en" ]; then
96
+ echo "❌ Unknown option: $arg"
97
+ echo "Run '$0' for usage information"
98
+ else
99
+ echo "❌ 알 수 없는 옵션: $arg"
100
+ echo "'$0'로 사용법을 확인하세요"
101
+ fi
102
+ exit 1
103
+ ;;
104
+ esac
105
+ done
106
+
107
+ if [ "$SYNC_MODE" = "--with-data" ] && [ "$APPLY_MODE" != "--apply" ]; then
108
+ if [ "$LANGUAGE" = "en" ]; then
109
+ echo "❌ --with-data requires --apply"
110
+ else
111
+ echo "❌ --with-data 는 --apply 와 함께 사용해야 합니다"
112
+ fi
113
+ exit 1
114
+ fi
115
+
116
+ build_cmd() {
117
+ local entity_name="$1"
118
+ local cmd=("$PROJECT_ROOT/bin/entity-cli" sync-index --entity="$entity_name")
119
+ if [ "$APPLY_MODE" = "--apply" ]; then
120
+ cmd+=(--apply)
121
+ fi
122
+ if [ "$SYNC_MODE" = "--with-data" ]; then
123
+ cmd+=(--with-data)
124
+ fi
125
+ echo "${cmd[@]}"
126
+ }
127
+
128
+ run_for_entity() {
129
+ local entity_name="$1"
130
+ local cmd
131
+ cmd=$(build_cmd "$entity_name")
132
+ echo "[sync] $entity_name"
133
+ if eval "$cmd"; then
134
+ return 0
135
+ fi
136
+ return 1
137
+ }
138
+
139
+ if [ "$TARGET" = "--all" ]; then
140
+ mapfile -t ENTITIES < <(find "$PROJECT_ROOT/entities" -type f -name '*.json' -printf '%f\n' | sed 's/\.json$//' | sort -u)
141
+
142
+ if [ ${#ENTITIES[@]} -eq 0 ]; then
143
+ if [ "$LANGUAGE" = "en" ]; then
144
+ echo "❌ No entity config files found in entities/"
145
+ else
146
+ echo "❌ entities/ 에 엔티티 설정 파일이 없습니다"
147
+ fi
148
+ exit 1
149
+ fi
150
+
151
+ total_count=${#ENTITIES[@]}
152
+ success_count=0
153
+ failed_count=0
154
+
155
+ for entity in "${ENTITIES[@]}"; do
156
+ if run_for_entity "$entity"; then
157
+ success_count=$((success_count + 1))
158
+ else
159
+ failed_count=$((failed_count + 1))
160
+ fi
161
+ done
162
+
163
+ echo ""
164
+ echo "[summary] target=all mode=${SYNC_MODE#--} apply=${APPLY_MODE#--} total=${total_count} success=${success_count} failed=${failed_count}"
165
+
166
+ if [ "$failed_count" -gt 0 ]; then
167
+ exit 1
168
+ fi
169
+ else
170
+ if run_for_entity "$TARGET"; then
171
+ echo ""
172
+ echo "[summary] target=${TARGET} mode=${SYNC_MODE#--} apply=${APPLY_MODE#--} total=1 success=1 failed=0"
173
+ else
174
+ echo ""
175
+ echo "[summary] target=${TARGET} mode=${SYNC_MODE#--} apply=${APPLY_MODE#--} total=1 success=0 failed=1"
176
+ exit 1
177
+ fi
178
+ fi
@@ -0,0 +1,117 @@
1
+ # update-server.ps1 — entity-server / entity-cli 바이너리 업데이트
2
+ #
3
+ # 사용법:
4
+ # .\scripts\update-server.ps1 # 도움말
5
+ # .\scripts\update-server.ps1 version # 현재 버전 + 최신 버전 확인
6
+ # .\scripts\update-server.ps1 latest # 최신 버전으로 업데이트
7
+ # .\scripts\update-server.ps1 1.5.0 # 특정 버전으로 업데이트
8
+
9
+ param([string]$Action = "")
10
+
11
+ $ErrorActionPreference = "Stop"
12
+
13
+ $REPO = "ehfuse/entity-server"
14
+ $BINARIES = @("entity-server", "entity-cli")
15
+ $PLATFORM = "windows"
16
+ $ARCH_TAG = "x64"
17
+ $ProjectRoot = Split-Path -Parent $PSScriptRoot
18
+
19
+ # ── 현재 버전 확인 ────────────────────────────────────────────────────────────
20
+
21
+ function Get-CurrentVer {
22
+ $BinPath = Join-Path $ProjectRoot "entity-server.exe"
23
+ if (Test-Path $BinPath) {
24
+ try {
25
+ $out = & $BinPath --version 2>$null
26
+ if ($out -match '(\d+\.\d+\.\d+)') { return $Matches[1] }
27
+ } catch {}
28
+ }
29
+ return "(없음)"
30
+ }
31
+
32
+ # ── 최신 버전 조회 ────────────────────────────────────────────────────────────
33
+
34
+ function Get-LatestVer {
35
+ try {
36
+ $resp = Invoke-RestMethod "https://api.github.com/repos/$REPO/releases/latest"
37
+ return $resp.tag_name -replace '^v', ''
38
+ } catch {
39
+ Write-Error "❌ 최신 버전을 가져오지 못했습니다: $_"
40
+ exit 1
41
+ }
42
+ }
43
+
44
+ # ── 설치 ──────────────────────────────────────────────────────────────────────
45
+
46
+ function Install-Version([string]$TargetVer) {
47
+ $TargetVer = $TargetVer -replace '^v', ''
48
+ $CurrentVer = Get-CurrentVer
49
+
50
+ Write-Host ""
51
+ Write-Host "📦 entity-server v$TargetVer 다운로드 중... ($PLATFORM-$ARCH_TAG)"
52
+ Write-Host ""
53
+
54
+ foreach ($Bin in $BINARIES) {
55
+ $FileName = "$Bin-$PLATFORM-$ARCH_TAG.exe"
56
+ $Url = "https://github.com/$REPO/releases/download/v$TargetVer/$FileName"
57
+ $Dest = Join-Path $ProjectRoot "$Bin.exe"
58
+ $Tmp = "$Dest.tmp"
59
+
60
+ Write-Host (" ↓ {0,-35}" -f $FileName) -NoNewline
61
+ try {
62
+ Invoke-WebRequest -Uri $Url -OutFile $Tmp -UseBasicParsing
63
+ Move-Item -Force $Tmp $Dest
64
+ Write-Host "✓"
65
+ } catch {
66
+ Write-Host "✗ 실패"
67
+ Write-Host " URL: $Url"
68
+ Write-Host " 오류: $_"
69
+ if (Test-Path $Tmp) { Remove-Item $Tmp -Force }
70
+ exit 1
71
+ }
72
+ }
73
+
74
+ Write-Host ""
75
+ Write-Host "✅ 업데이트 완료: v$CurrentVer → v$TargetVer"
76
+ Write-Host " 서버를 재시작하면 새 버전이 적용됩니다."
77
+ }
78
+
79
+ # ── 서브커맨드 분기 ───────────────────────────────────────────────────────────
80
+
81
+ switch ($Action) {
82
+ "" {
83
+ Write-Host "update-server.ps1 — entity-server / entity-cli 바이너리 업데이트"
84
+ Write-Host ""
85
+ Write-Host "사용법:"
86
+ Write-Host " .\scripts\update-server.ps1 version 현재 버전 + 최신 버전 확인"
87
+ Write-Host " .\scripts\update-server.ps1 latest 최신 버전으로 업데이트"
88
+ Write-Host " .\scripts\update-server.ps1 <버전> 특정 버전으로 업데이트"
89
+ Write-Host ""
90
+ Write-Host "예시:"
91
+ Write-Host " .\scripts\update-server.ps1 version"
92
+ Write-Host " .\scripts\update-server.ps1 latest"
93
+ Write-Host " .\scripts\update-server.ps1 1.5.0"
94
+ }
95
+ "version" {
96
+ Write-Host "🔍 버전 확인 중..."
97
+ $Current = Get-CurrentVer
98
+ $Latest = Get-LatestVer
99
+ Write-Host ""
100
+ Write-Host " 현재 버전: v$Current"
101
+ Write-Host " 최신 버전: v$Latest"
102
+ Write-Host ""
103
+ if ($Current -eq $Latest) {
104
+ Write-Host "✅ 최신 버전입니다."
105
+ } else {
106
+ Write-Host "💡 업데이트 가능: .\scripts\update-server.ps1 latest"
107
+ }
108
+ }
109
+ "latest" {
110
+ Write-Host "🔍 최신 버전 확인 중..."
111
+ $Latest = Get-LatestVer
112
+ Install-Version $Latest
113
+ }
114
+ default {
115
+ Install-Version $Action
116
+ }
117
+ }
@@ -0,0 +1,165 @@
1
+ #!/bin/bash
2
+ # update-server.sh — entity-server / entity-cli 바이너리 업데이트
3
+ #
4
+ # 사용법:
5
+ # ./scripts/update-server.sh # 도움말
6
+ # ./scripts/update-server.sh version # 현재 버전 + 최신 버전 확인
7
+ # ./scripts/update-server.sh latest # 최신 버전으로 업데이트
8
+ # ./scripts/update-server.sh 1.5.0 # 특정 버전으로 업데이트
9
+
10
+ set -e
11
+
12
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
14
+ REPO="ehfuse/entity-server"
15
+ BINARIES=("entity-server" "entity-cli")
16
+
17
+ # ── 플랫폼 감지 ───────────────────────────────────────────────────────────────
18
+
19
+ OS="$(uname -s)"
20
+ ARCH="$(uname -m)"
21
+
22
+ case "$OS" in
23
+ Linux) PLATFORM="linux" ;;
24
+ Darwin) PLATFORM="darwin" ;;
25
+ *)
26
+ echo "❌ 지원하지 않는 OS: $OS"
27
+ echo " Windows 는 scripts\\update-server.ps1 을 사용하세요."
28
+ exit 1
29
+ ;;
30
+ esac
31
+
32
+ case "$ARCH" in
33
+ x86_64) ARCH_TAG="x64" ;;
34
+ aarch64|arm64) ARCH_TAG="arm64" ;;
35
+ *)
36
+ echo "❌ 지원하지 않는 아키텍처: $ARCH"
37
+ exit 1
38
+ ;;
39
+ esac
40
+
41
+ # ── 현재 버전 확인 ────────────────────────────────────────────────────────────
42
+
43
+ _current_ver() {
44
+ local bin="$PROJECT_ROOT/entity-server"
45
+ if [ -x "$bin" ]; then
46
+ "$bin" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "(알 수 없음)"
47
+ else
48
+ echo "(없음)"
49
+ fi
50
+ }
51
+
52
+ # ── 최신 버전 조회 ────────────────────────────────────────────────────────────
53
+
54
+ _latest_ver() {
55
+ local ver
56
+ if command -v curl >/dev/null 2>&1; then
57
+ ver="$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" \
58
+ | grep '"tag_name"' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)"
59
+ elif command -v wget >/dev/null 2>&1; then
60
+ ver="$(wget -qO- "https://api.github.com/repos/${REPO}/releases/latest" \
61
+ | grep '"tag_name"' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)"
62
+ else
63
+ echo "❌ curl 또는 wget 이 필요합니다." >&2
64
+ exit 1
65
+ fi
66
+ if [ -z "$ver" ]; then
67
+ echo "❌ 최신 버전을 가져오지 못했습니다. 네트워크 연결을 확인하세요." >&2
68
+ exit 1
69
+ fi
70
+ echo "$ver"
71
+ }
72
+
73
+ # ── 다운로드 ──────────────────────────────────────────────────────────────────
74
+
75
+ _download() {
76
+ local url="$1"
77
+ local dest="$2"
78
+ local tmp="${dest}.tmp"
79
+
80
+ if command -v curl >/dev/null 2>&1; then
81
+ curl -fsSL --retry 3 -o "$tmp" "$url"
82
+ elif command -v wget >/dev/null 2>&1; then
83
+ wget -q -O "$tmp" "$url"
84
+ else
85
+ echo "❌ curl 또는 wget 이 필요합니다."
86
+ exit 1
87
+ fi
88
+
89
+ mv "$tmp" "$dest"
90
+ chmod +x "$dest"
91
+ }
92
+
93
+ _install() {
94
+ local target_ver="${1#v}" # v 접두사 제거
95
+ local current_ver
96
+ current_ver="$(_current_ver)"
97
+
98
+ echo ""
99
+ echo "📦 entity-server v${target_ver} 다운로드 중... (${PLATFORM}-${ARCH_TAG})"
100
+ echo ""
101
+
102
+ for BIN in "${BINARIES[@]}"; do
103
+ local file="${BIN}-${PLATFORM}-${ARCH_TAG}"
104
+ local url="https://github.com/${REPO}/releases/download/v${target_ver}/${file}"
105
+ local dest="$PROJECT_ROOT/$BIN"
106
+
107
+ printf " ↓ %-32s" "$file"
108
+ if _download "$url" "$dest" 2>/dev/null; then
109
+ echo "✓"
110
+ else
111
+ echo "✗ 실패"
112
+ echo " URL: $url"
113
+ exit 1
114
+ fi
115
+ done
116
+
117
+ echo ""
118
+ echo "✅ 업데이트 완료: v${current_ver} → v${target_ver}"
119
+ echo " 서버를 재시작하면 새 버전이 적용됩니다."
120
+ }
121
+
122
+ # ── 서브커맨드 분기 ───────────────────────────────────────────────────────────
123
+
124
+ ARG="${1:-}"
125
+
126
+ case "$ARG" in
127
+ "")
128
+ echo "update-server.sh — entity-server / entity-cli 바이너리 업데이트"
129
+ echo ""
130
+ echo "사용법:"
131
+ echo " ./scripts/update-server.sh version 현재 버전 + 최신 버전 확인"
132
+ echo " ./scripts/update-server.sh latest 최신 버전으로 업데이트"
133
+ echo " ./scripts/update-server.sh <버전> 특정 버전으로 업데이트"
134
+ echo ""
135
+ echo "예시:"
136
+ echo " ./scripts/update-server.sh version"
137
+ echo " ./scripts/update-server.sh latest"
138
+ echo " ./scripts/update-server.sh 1.5.0"
139
+ ;;
140
+
141
+ "version")
142
+ echo "🔍 버전 확인 중..."
143
+ CURRENT="$(_current_ver)"
144
+ LATEST="$(_latest_ver)"
145
+ echo ""
146
+ echo " 현재 버전: v${CURRENT}"
147
+ echo " 최신 버전: v${LATEST}"
148
+ echo ""
149
+ if [ "$CURRENT" = "$LATEST" ]; then
150
+ echo "✅ 최신 버전입니다."
151
+ else
152
+ echo "💡 업데이트 가능: ./scripts/update-server.sh latest"
153
+ fi
154
+ ;;
155
+
156
+ "latest")
157
+ echo "🔍 최신 버전 확인 중..."
158
+ LATEST="$(_latest_ver)"
159
+ _install "$LATEST"
160
+ ;;
161
+
162
+ *)
163
+ _install "$ARG"
164
+ ;;
165
+ esac