create-entity-server 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-entity-server",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Create a new entity-server project in one command — like create-react-app or create-vite.",
5
5
  "keywords": [
6
6
  "entity-server",
@@ -0,0 +1,12 @@
1
+ {
2
+ "_comment": "브라우저 직접 통신용 CSRF 설정 예시. access/refresh 는 HttpOnly 쿠키, CSRF 는 double-submit cookie + header 로 사용합니다.",
3
+ "enabled": true,
4
+ "header_name": "X-CSRF-Token",
5
+ "cookie_name": "_csrf",
6
+ "cookie_path": "/",
7
+ "cookie_max_age_sec": 86400,
8
+ "same_site": "Lax",
9
+ "issue_on_health": true,
10
+ "protect_methods": ["POST", "PUT", "PATCH", "DELETE"],
11
+ "ignore_paths": ["/v1/health", "/v1/alimtalk/webhook/"]
12
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "account",
3
- "description": "JWT 로그인/인증용 계정 정보. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "JWT 로그인/인증용 계정 정보.",
4
4
  "fields": {
5
5
  "email": {
6
6
  "index": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "account_audit",
3
- "description": "account 감사 로그. account.json 훅(after_insert/after_update/after_delete)에 의해 자동 기록됩니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "account 감사 로그. account.json 훅(after_insert/after_update/after_delete)에 의해 자동 기록됩니다.",
4
4
  "hard_delete": true,
5
5
  "read_only": true,
6
6
  "compress": true,
@@ -14,11 +14,7 @@
14
14
  "action": {
15
15
  "index": true,
16
16
  "comment": "작업 유형 (after_insert → INSERT, after_update → UPDATE, after_delete → DELETE)",
17
- "type": [
18
- "INSERT",
19
- "UPDATE",
20
- "DELETE"
21
- ],
17
+ "type": ["INSERT", "UPDATE", "DELETE"],
22
18
  "required": true
23
19
  },
24
20
  "email": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "account_device",
3
- "description": "회원 계정 기기 정보 및 푸시 토큰 관리. account_seq로 계정과 연결되며 회원 전용으로 사용합니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "회원 계정 기기 정보 및 푸시 토큰 관리. account_seq로 계정과 연결되며 회원 전용으로 사용합니다.",
4
4
  "license_scope": false,
5
5
  "fields": {
6
6
  "account_seq": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "account_login_log",
3
- "description": "account_login_log 엔티티. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "account_login_log 엔티티.",
4
4
  "compress": true,
5
5
  "fields": {
6
6
  "browser": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anon_device",
3
- "description": "비회원 디바이스 식별 및 사용 제한 집계. device_id 쿠키 값 기반으로 추적하며 익명 사용자 전용으로 사용합니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "비회원 디바이스 식별 및 사용 제한 집계. device_id 쿠키 값 기반으로 추적하며 익명 사용자 전용으로 사용합니다.",
4
4
  "license_scope": false,
5
5
  "fields": {
6
6
  "id": {
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "api_keys",
3
- "description": "API 키 및 HMAC 시크릿 관리. account_seq는 JWT 인증 시에만 FK. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "API 키 및 HMAC 시크릿 관리. account_seq는 JWT 인증 시에만 FK.",
4
4
  "license_scope": false,
5
5
  "fields": {
6
6
  "key_value": {
7
- "index": true,
8
7
  "comment": "API 키 Hash 값",
9
8
  "required": true,
10
9
  "unique": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "license",
3
- "description": "license 엔티티. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "license 엔티티.",
4
4
  "cache": {
5
5
  "ttl_seconds": 300
6
6
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rbac_roles",
3
- "description": "역할 기반 접근 제어 역할 정의. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "역할 기반 접근 제어 역할 정의.",
4
4
  "license_scope": false,
5
5
  "hard_delete": true,
6
6
  "fields": {
@@ -18,9 +18,7 @@
18
18
  {
19
19
  "name": "admin",
20
20
  "description": "전체 권한 (모든 엔티티 CRUD + 관리)",
21
- "permissions": [
22
- "*"
23
- ]
21
+ "permissions": ["*"]
24
22
  },
25
23
  {
26
24
  "name": "editor",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backup_log",
3
- "description": "백업 작업 이력. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "백업 작업 이력.",
4
4
  "license_scope": false,
5
5
  "hard_delete": true,
6
6
  "history": false,
@@ -8,11 +8,7 @@
8
8
  "fields": {
9
9
  "backup_type": {
10
10
  "index": true,
11
- "type": [
12
- "data",
13
- "file",
14
- "full"
15
- ],
11
+ "type": ["data", "file", "full"],
16
12
  "required": true
17
13
  },
18
14
  "finished_time": {
@@ -23,12 +19,7 @@
23
19
  },
24
20
  "status": {
25
21
  "index": true,
26
- "type": [
27
- "running",
28
- "completed",
29
- "partial",
30
- "failed"
31
- ],
22
+ "type": ["running", "completed", "partial", "failed"],
32
23
  "required": true
33
24
  },
34
25
  "session_id": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smtp_log",
3
- "description": "SMTP 이메일 발송 이력. 발송 결과 추적 및 재시도 관리용. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "SMTP 이메일 발송 이력. 발송 결과 추적 및 재시도 관리용.",
4
4
  "license_scope": false,
5
5
  "hard_delete": true,
6
6
  "history": false,
@@ -29,13 +29,7 @@
29
29
  },
30
30
  "status": {
31
31
  "index": true,
32
- "type": [
33
- "pending",
34
- "processing",
35
- "sent",
36
- "failed",
37
- "expired"
38
- ],
32
+ "type": ["pending", "processing", "sent", "failed", "expired"],
39
33
  "default": "pending",
40
34
  "required": true
41
35
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smtp_msg",
3
- "description": "SMTP 이메일 트리거 엔티티. insert 시 smtp hook으로 비동기 발송. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "SMTP 이메일 트리거 엔티티. insert 시 smtp hook으로 비동기 발송.",
4
4
  "hard_delete": true,
5
5
  "history": false,
6
6
  "fields": {
@@ -11,11 +11,7 @@
11
11
  },
12
12
  "status": {
13
13
  "index": true,
14
- "type": [
15
- "queued",
16
- "sent",
17
- "failed"
18
- ],
14
+ "type": ["queued", "sent", "failed"],
19
15
  "default": "queued",
20
16
  "required": true
21
17
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file_backup_log",
3
- "description": "파일 백업 작업 로그. 스토리지 간 백업 동기화 이력을 기록합니다. 서버 내부 백업 고루틴이 자동 기록. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "파일 백업 작업 로그. 스토리지 간 백업 동기화 이력을 기록합니다. 서버 내부 백업 고루틴이 자동 기록.",
4
4
  "license_scope": false,
5
5
  "history": false,
6
6
  "hard_delete": true,
@@ -14,12 +14,7 @@
14
14
  "status": {
15
15
  "index": true,
16
16
  "comment": "작업 상태",
17
- "type": [
18
- "running",
19
- "completed",
20
- "partial",
21
- "failed"
22
- ],
17
+ "type": ["running", "completed", "partial", "failed"],
23
18
  "default": "running",
24
19
  "required": true
25
20
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file_download_log",
3
- "description": "파일 다운로드 이력. 누가 어떤 파일을 언제 다운로드했는지 기록합니다. 감사(audit) 및 통계 목적. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "파일 다운로드 이력. 누가 어떤 파일을 언제 다운로드했는지 기록합니다. 감사(audit) 및 통계 목적.",
4
4
  "hard_delete": true,
5
5
  "history": false,
6
6
  "compress": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file_meta",
3
- "description": "파일 메타데이터. 업로드된 파일의 저장 위치·크기·해시·상태를 관리합니다. 파일 핸들러가 자동 기록하며 API를 통한 직접 수정은 허용되지 않습니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "파일 메타데이터. 업로드된 파일의 저장 위치·크기·해시·상태를 관리합니다. 파일 핸들러가 자동 기록하며 API를 통한 직접 수정은 허용되지 않습니다.",
4
4
  "history": false,
5
5
  "hard_delete": true,
6
6
  "read_only": true,
@@ -8,13 +8,7 @@
8
8
  "backup_status": {
9
9
  "index": true,
10
10
  "comment": "백업 동기화 상태",
11
- "type": [
12
- "none",
13
- "pending",
14
- "synced",
15
- "failed",
16
- "skipped"
17
- ],
11
+ "type": ["none", "pending", "synced", "failed", "skipped"],
18
12
  "default": "none"
19
13
  },
20
14
  "size": {
@@ -25,12 +19,7 @@
25
19
  "status": {
26
20
  "index": true,
27
21
  "comment": "파일 상태",
28
- "type": [
29
- "active",
30
- "pending",
31
- "orphan",
32
- "deleted"
33
- ],
22
+ "type": ["active", "pending", "orphan", "deleted"],
34
23
  "default": "pending",
35
24
  "required": true
36
25
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "system_audit_log",
3
- "description": "시스템 감사 로그. 서버 레벨에서 자동 기록되며 API를 통한 직접 수정은 허용되지 않습니다. JWT 인증 시에만 account_seq 기록. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "시스템 감사 로그. 서버 레벨에서 자동 기록되며 API를 통한 직접 수정은 허용되지 않습니다. JWT 인증 시에만 account_seq 기록.",
4
4
  "license_scope": false,
5
5
  "hard_delete": true,
6
6
  "history_ttl": 0,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "company",
3
- "description": "company Entity. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "company Entity.",
4
4
  "fields": {
5
5
  "company_name": {
6
6
  "index": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goods",
3
- "description": "goods Entity. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "goods Entity.",
4
4
  "fields": {
5
5
  "name": {
6
6
  "index": true,
@@ -11,11 +11,7 @@
11
11
  "category": {
12
12
  "index": true,
13
13
  "comment": "카테고리",
14
- "type": [
15
- "전자제품",
16
- "가구",
17
- "생활용품"
18
- ]
14
+ "type": ["전자제품", "가구", "생활용품"]
19
15
  },
20
16
  "price": {
21
17
  "index": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "todo",
3
- "description": "todo Entity. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
3
+ "description": "todo Entity.",
4
4
  "fields": {
5
5
  "title": {
6
6
  "index": true,
@@ -9,10 +9,7 @@
9
9
  "status": {
10
10
  "index": true,
11
11
  "comment": "상태",
12
- "type": [
13
- "pending",
14
- "done"
15
- ]
12
+ "type": ["pending", "done"]
16
13
  }
17
14
  }
18
15
  }
@@ -10,9 +10,9 @@
10
10
  // @ts-ignore
11
11
  import { useEffect, useState } from "react";
12
12
  // @ts-ignore
13
- import { useEntityServer } from "entity-server-client/react";
13
+ import { useEntityServer } from "entity-client/react";
14
14
  // @ts-ignore
15
- import type { EntityListResult } from "entity-server-client";
15
+ import type { EntityListResult } from "entity-client";
16
16
 
17
17
  interface Product {
18
18
  seq: number;
@@ -213,23 +213,10 @@ stop_pid_with_confirm() {
213
213
  echo "Running process ($reason):"
214
214
  echo " PID USER ELAPSED COMMAND"
215
215
  echo " $proc_info"
216
- echo ""
217
- read -r -p "Stop this process? [y/N]: " input
218
216
  else
219
217
  echo "실행 중인 프로세스($reason):"
220
218
  echo " PID USER 실행시간 COMMAND"
221
219
  echo " $proc_info"
222
- echo ""
223
- read -r -p "이 프로세스를 중지할까요? [y/N]: " input
224
- fi
225
- input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
226
- if [ "$input" != "y" ] && [ "$input" != "yes" ] && [ "$input" != "ㅛ" ]; then
227
- if [ "$LANGUAGE" = "en" ]; then
228
- echo "Canceled."
229
- else
230
- echo "취소되었습니다."
231
- fi
232
- return 0
233
220
  fi
234
221
 
235
222
  kill "$pid" 2>/dev/null
@@ -435,8 +422,10 @@ fi
435
422
  if [ ! -f "$SERVER_BIN" ]; then
436
423
  if [ "$LANGUAGE" = "en" ]; then
437
424
  echo "❌ entity-server binary not found (bin/entity-server or ./entity-server)"
425
+ echo " Run ./scripts/update-server.sh to download the latest binary."
438
426
  else
439
427
  echo "❌ entity-server 바이너리 파일이 없습니다 (bin/entity-server 또는 ./entity-server)"
428
+ echo " ./scripts/update-server.sh 를 실행하여 바이너리를 다운로드하세요."
440
429
  fi
441
430
  exit 1
442
431
  fi
@@ -2,14 +2,14 @@
2
2
 
3
3
  # Register entity-server as a systemd service using the current project path.
4
4
 
5
- set -e
5
+ set -euo pipefail
6
6
 
7
7
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
8
  PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
9
9
 
10
10
  # Load language from .env
11
11
  if [ -f "$PROJECT_ROOT/.env" ]; then
12
- LANGUAGE=$(grep '^LANGUAGE=' "$PROJECT_ROOT/.env" | cut -d '=' -f2)
12
+ LANGUAGE=$(sed -n 's/^LANGUAGE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
13
13
  fi
14
14
  LANGUAGE=${LANGUAGE:-ko}
15
15
 
@@ -2,14 +2,14 @@
2
2
 
3
3
  # Remove entity-server systemd service.
4
4
 
5
- set -e
5
+ set -euo pipefail
6
6
 
7
7
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
8
  PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
9
9
 
10
10
  # Load language from .env
11
11
  if [ -f "$PROJECT_ROOT/.env" ]; then
12
- LANGUAGE=$(grep '^LANGUAGE=' "$PROJECT_ROOT/.env" | cut -d '=' -f2)
12
+ LANGUAGE=$(sed -n 's/^LANGUAGE=//p' "$PROJECT_ROOT/.env" | tail -n 1)
13
13
  fi
14
14
  LANGUAGE=${LANGUAGE:-ko}
15
15