@spfn/cms 0.1.0-alpha.64 → 0.1.0-alpha.65

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 (103) hide show
  1. package/README.md +67 -30
  2. package/dist/actions-CwvmPG0e.d.ts +296 -0
  3. package/dist/actions.d.ts +1 -143
  4. package/dist/actions.js +5 -5
  5. package/dist/actions.js.map +1 -1
  6. package/dist/api.d.ts +376 -0
  7. package/dist/api.js +364 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/client.d.ts +115 -141
  10. package/dist/client.js +860 -63
  11. package/dist/client.js.map +1 -1
  12. package/dist/{types.d.ts → index-Dh5FjWzR.d.ts} +32 -1
  13. package/dist/index.d.ts +21 -43
  14. package/dist/index.js +556 -1061
  15. package/dist/index.js.map +1 -1
  16. package/dist/label-sync-generator-B0EmvtWM.d.ts +32 -0
  17. package/dist/{contracts → lib/contracts}/labels.d.ts +13 -12
  18. package/dist/{contracts → lib/contracts}/labels.js +7 -7
  19. package/dist/lib/contracts/labels.js.map +1 -0
  20. package/dist/{contracts → lib/contracts}/published-cache.d.ts +3 -2
  21. package/dist/{contracts → lib/contracts}/published-cache.js +2 -2
  22. package/dist/lib/contracts/published-cache.js.map +1 -0
  23. package/dist/{contracts → lib/contracts}/values.d.ts +6 -4
  24. package/dist/{contracts → lib/contracts}/values.js +3 -3
  25. package/dist/lib/contracts/values.js.map +1 -0
  26. package/dist/{entities → server/entities}/cms-audit-logs.js +3 -3
  27. package/dist/server/entities/cms-audit-logs.js.map +1 -0
  28. package/dist/{entities → server/entities}/cms-draft-cache.js +1 -1
  29. package/dist/server/entities/cms-draft-cache.js.map +1 -0
  30. package/dist/{entities → server/entities}/cms-label-values.js +3 -3
  31. package/dist/server/entities/cms-label-values.js.map +1 -0
  32. package/dist/{entities → server/entities}/cms-label-versions.js +3 -3
  33. package/dist/server/entities/cms-label-versions.js.map +1 -0
  34. package/dist/{entities → server/entities}/cms-labels.js +1 -1
  35. package/dist/server/entities/cms-labels.js.map +1 -0
  36. package/dist/{entities → server/entities}/cms-published-cache.js +1 -1
  37. package/dist/server/entities/cms-published-cache.js.map +1 -0
  38. package/dist/{entities → server/entities}/index.js +6 -6
  39. package/dist/server/entities/index.js.map +1 -0
  40. package/dist/{generators → server/generators}/index.d.ts +1 -2
  41. package/dist/{generators → server/generators}/index.js +169 -75
  42. package/dist/server/generators/index.js.map +1 -0
  43. package/dist/server/labels/index.d.ts +1 -0
  44. package/dist/{labels → server/labels}/index.js +1 -1
  45. package/dist/server/labels/index.js.map +1 -0
  46. package/dist/{repositories → server/repositories}/index.js +11 -11
  47. package/dist/server/repositories/index.js.map +1 -0
  48. package/dist/{routes → server/routes}/labels/[id]/index.js +20 -20
  49. package/dist/server/routes/labels/[id]/index.js.map +1 -0
  50. package/dist/{routes → server/routes}/labels/by-key/[key]/index.js +20 -20
  51. package/dist/server/routes/labels/by-key/[key]/index.js.map +1 -0
  52. package/dist/{routes → server/routes}/labels/index.d.ts +2 -2
  53. package/dist/{routes → server/routes}/labels/index.js +21 -22
  54. package/dist/server/routes/labels/index.js.map +1 -0
  55. package/dist/{routes → server/routes}/published-cache/index.js +14 -14
  56. package/dist/server/routes/published-cache/index.js.map +1 -0
  57. package/dist/{routes → server/routes}/values/[labelId]/[version]/index.js +16 -16
  58. package/dist/server/routes/values/[labelId]/[version]/index.js.map +1 -0
  59. package/dist/{routes → server/routes}/values/[labelId]/index.js +16 -16
  60. package/dist/server/routes/values/[labelId]/index.js.map +1 -0
  61. package/dist/server.d.ts +76 -7
  62. package/dist/server.js +1601 -42
  63. package/dist/server.js.map +1 -1
  64. package/package.json +37 -35
  65. package/dist/contracts/labels.js.map +0 -1
  66. package/dist/contracts/published-cache.js.map +0 -1
  67. package/dist/contracts/values.js.map +0 -1
  68. package/dist/entities/cms-audit-logs.js.map +0 -1
  69. package/dist/entities/cms-draft-cache.js.map +0 -1
  70. package/dist/entities/cms-label-values.js.map +0 -1
  71. package/dist/entities/cms-label-versions.js.map +0 -1
  72. package/dist/entities/cms-labels.js.map +0 -1
  73. package/dist/entities/cms-published-cache.js.map +0 -1
  74. package/dist/entities/index.js.map +0 -1
  75. package/dist/generators/index.js.map +0 -1
  76. package/dist/label-sync-generator-lQrcVfja.d.ts +0 -36
  77. package/dist/labels/index.d.ts +0 -34
  78. package/dist/labels/index.js.map +0 -1
  79. package/dist/repositories/index.js.map +0 -1
  80. package/dist/routes/labels/[id]/index.js.map +0 -1
  81. package/dist/routes/labels/by-key/[key]/index.js.map +0 -1
  82. package/dist/routes/labels/index.js.map +0 -1
  83. package/dist/routes/published-cache/index.js.map +0 -1
  84. package/dist/routes/values/[labelId]/[version]/index.js.map +0 -1
  85. package/dist/routes/values/[labelId]/index.js.map +0 -1
  86. package/dist/store.d.ts +0 -81
  87. package/dist/store.js +0 -403
  88. package/dist/store.js.map +0 -1
  89. package/dist/types.js +0 -1
  90. package/dist/types.js.map +0 -1
  91. package/dist/{entities → server/entities}/cms-audit-logs.d.ts +0 -0
  92. package/dist/{entities → server/entities}/cms-draft-cache.d.ts +0 -0
  93. package/dist/{entities → server/entities}/cms-label-values.d.ts +0 -0
  94. package/dist/{entities → server/entities}/cms-label-versions.d.ts +0 -0
  95. package/dist/{entities → server/entities}/cms-labels.d.ts +0 -0
  96. package/dist/{entities → server/entities}/cms-published-cache.d.ts +0 -0
  97. package/dist/{entities → server/entities}/index.d.ts +0 -0
  98. package/dist/{repositories → server/repositories}/index.d.ts +14 -14
  99. /package/dist/{routes → server/routes}/labels/_id_/index.d.ts +0 -0
  100. /package/dist/{routes → server/routes}/labels/by-key/_key_/index.d.ts +0 -0
  101. /package/dist/{routes → server/routes}/published-cache/index.d.ts +0 -0
  102. /package/dist/{routes → server/routes}/values/_labelId_/_version_/index.d.ts +0 -0
  103. /package/dist/{routes → server/routes}/values/_labelId_/index.d.ts +0 -0
package/README.md CHANGED
@@ -16,7 +16,7 @@ Content Management System for Next.js with JSON-based labels and automatic datab
16
16
 
17
17
  ## Installation
18
18
 
19
- ### Recommended: Using SPFN CLI (Automatic Database Setup)
19
+ ### Recommended: Using Superfunction CLI (Automatic Database Setup)
20
20
 
21
21
  ```bash
22
22
  pnpm spfn add @spfn/cms
@@ -59,7 +59,7 @@ pnpm spfn db migrate # Apply migrations
59
59
  Create JSON files organized by sections and categories:
60
60
 
61
61
  ```
62
- src/cms/labels/
62
+ src/lib/labels/
63
63
  layout/ ← Section name
64
64
  nav.json ← Category
65
65
  footer.json
@@ -68,7 +68,7 @@ src/cms/labels/
68
68
  features.json
69
69
  ```
70
70
 
71
- **Example:** `src/cms/labels/layout/nav.json`
71
+ **Example:** `src/lib/labels/layout/nav.json`
72
72
 
73
73
  ```json
74
74
  {
@@ -89,7 +89,7 @@ src/cms/labels/
89
89
  }
90
90
  ```
91
91
 
92
- **Multi-language example:** `src/cms/labels/home/hero.json`
92
+ **Multi-language example:** `src/lib/labels/home/hero.json`
93
93
 
94
94
  ```json
95
95
  {
@@ -110,7 +110,7 @@ src/cms/labels/
110
110
  }
111
111
  ```
112
112
 
113
- **Variable substitution:** `src/cms/labels/layout/footer.json`
113
+ **Variable substitution:** `src/lib/labels/layout/footer.json`
114
114
 
115
115
  ```json
116
116
  {
@@ -127,13 +127,14 @@ Configure `src/server/server.config.ts`:
127
127
 
128
128
  ```typescript
129
129
  import type { ServerConfig } from '@spfn/core/server';
130
- import { initLabelSync } from '@spfn/cms';
130
+ import { initLabelSync } from '@spfn/cms/server';
131
+ import { DEFAULT_LABELS_DIR } from '@spfn/cms';
131
132
 
132
133
  export default {
133
134
  beforeRoutes: async (app) => {
134
135
  await initLabelSync({
135
136
  verbose: true,
136
- labelsDir: 'src/cms/labels' // Optional, this is the default
137
+ // labelsDir: DEFAULT_LABELS_DIR // Optional, this is the default
137
138
  });
138
139
  },
139
140
  } satisfies ServerConfig;
@@ -205,7 +206,7 @@ export default function Nav() {
205
206
  ## File Structure
206
207
 
207
208
  ```
208
- src/cms/labels/
209
+ src/lib/labels/
209
210
  layout/ # Section: layout
210
211
  nav.json # Category: nav
211
212
  footer.json # Category: footer
@@ -221,7 +222,7 @@ src/cms/labels/
221
222
 
222
223
  Example:
223
224
  ```
224
- src/cms/labels/layout/nav.json:
225
+ src/lib/labels/layout/nav.json:
225
226
  key: "layout.nav.team" → t('nav.team') in code
226
227
  ```
227
228
 
@@ -279,6 +280,18 @@ t('greeting', undefined, { name: 'John' })
279
280
 
280
281
  ## Configuration
281
282
 
283
+ ### Default Paths
284
+
285
+ The default label directory path is defined as a constant:
286
+
287
+ ```typescript
288
+ import { DEFAULT_LABELS_DIR } from '@spfn/cms';
289
+
290
+ console.log(DEFAULT_LABELS_DIR); // 'src/lib/labels'
291
+ ```
292
+
293
+ This constant is used throughout the CMS package and can be referenced in your code to avoid hardcoding paths.
294
+
282
295
  ### Environment Variables
283
296
 
284
297
  Configure CMS behavior via environment variables in `.env.local`:
@@ -344,7 +357,7 @@ export default async function RootLayout({ children }) {
344
357
  ```typescript
345
358
  // Client Component
346
359
  'use client';
347
- import { getLocale } from '@spfn/cms/actions';
360
+ import { getLocale } from '@spfn/cms/client';
348
361
  import { useEffect, useState } from 'react';
349
362
 
350
363
  export default function LanguageSwitcher() {
@@ -399,7 +412,7 @@ const { t: tEn } = await getSection('home', 'en');
399
412
  ## Architecture
400
413
 
401
414
  ```
402
- JSON Files (src/cms/labels/**/*.json)
415
+ JSON Files (src/lib/labels/**/*.json)
403
416
 
404
417
  loadLabelsFromJson()
405
418
 
@@ -425,49 +438,73 @@ JSON Files (src/cms/labels/**/*.json)
425
438
 
426
439
  ## API Reference
427
440
 
428
- ### Server-side API
441
+ ### Common API (`@spfn/cms`)
429
442
 
443
+ **Configuration:**
444
+ - `getCmsConfig()` - Get current CMS configuration
445
+ - `configureCms(config)` - Update configuration (runtime)
446
+ - `resetCmsConfig()` - Reset configuration to defaults
447
+
448
+ **Constants:**
449
+ - `DEFAULT_LABELS_DIR` - Default label directory path (`'src/lib/labels'`)
450
+ - `LOCALE_COOKIE_KEY` - Locale cookie key constant
451
+ - Locale helpers: `getLocaleInfo()`, `getSupportedLocales()`, `getFlag()`, `getDialCode()`, `isRTL()`
452
+
453
+ **Types:**
454
+ - `SectionData`, `SectionAPI`, `CmsConfig`, `LocaleInfo`, `SupportedLocale`
455
+
456
+ ### Server-side API (`@spfn/cms/server`)
457
+
458
+ **Server Components:**
430
459
  - `getSection(section, locale?)` - Get section labels (auto-detects locale if not specified)
431
460
  - `getSections(sections, locale?)` - Get multiple sections (auto-detects locale if not specified)
461
+
462
+ **Backend/Sync:**
432
463
  - `initLabelSync(options?)` - Sync labels on server startup
464
+ - `syncAll(sections, options?)` - Sync all sections
465
+ - `syncSection(definition, options?)` - Sync specific section
466
+ - `loadLabelsFromJson(labelsDir)` - Load labels from JSON files
433
467
 
434
- ### Server Actions API (`@spfn/cms/actions`)
468
+ **Repositories & Entities:**
469
+ - All repository and entity exports
435
470
 
436
- Available for both server and client components:
471
+ **Codegen:**
472
+ - `createLabelSyncGenerator(config?)` - Generator factory
473
+ - `LabelSyncGenerator` - Generator class
437
474
 
475
+ **Locale (Server Actions):**
438
476
  - `getLocale()` - Get current locale (cookie → browser → default)
439
477
  - `setLocale(locale)` - Set locale (saves to cookie)
440
478
  - `getLocales()` - Get supported locale list
441
- - `LOCALE_COOKIE_KEY` - Locale cookie key constant
479
+ - `getLocaleWithInfo()`, `getLocalesWithInfo()`, `isValidLocale()`
442
480
 
443
- ### Configuration API
481
+ ### Server Actions API (`@spfn/cms/actions`)
444
482
 
445
- - `getCmsConfig()` - Get current CMS configuration
446
- - `configureCms(config)` - Update configuration (runtime)
447
- - `resetCmsConfig()` - Reset configuration to defaults
483
+ *Alias for `@spfn/cms/server` locale functions - available for both server and client components*
448
484
 
449
485
  ### Client-side API (`@spfn/cms/client`)
450
486
 
451
487
  - `useSection(section, options?)` - Section labels hook
452
488
  - `useSections(sections)` - Multiple sections hook
453
489
  - `useCmsStore()` - CMS store hook
454
- - `cmsApi` - CMS API client
455
490
  - `InitCms` - Client initialization component
456
491
 
457
- ### Sync API
458
-
459
- - `loadLabelsFromJson(labelsDir)` - Load labels from JSON files
460
- - `syncAll(sections, options?)` - Sync all sections
461
- - `syncSection(definition, options?)` - Sync specific section
492
+ ### Management API (`@spfn/cms/api`)
462
493
 
463
- ### Codegen Integration
494
+ ⚠️ **Admin only** - Use with proper authentication
464
495
 
465
- - `createLabelSyncGenerator(config?)` - Generator factory
466
- - `LabelSyncGenerator` - Generator class
496
+ - `cmsApi.cmsLabels.get(options?)` - List labels with filters
497
+ - `cmsApi.cmsLabels.getById(options)` - Get label by ID
498
+ - `cmsApi.cmsLabels.post(options)` - Create new label
499
+ - `cmsApi.cmsLabels.update(options)` - Update label
500
+ - `cmsApi.cmsLabels.delete(options)` - Delete label
501
+ - `cmsApi.cmsLabelsByKey` - Get labels by key
502
+ - `cmsApi.cmsValues` - Manage label values
503
+ - `cmsApi.cmsPublishedCache.get(options)` - Get published cache
467
504
 
468
505
  ## Development Workflow
469
506
 
470
- 1. **Create/Edit JSON files** in `src/cms/labels/`
507
+ 1. **Create/Edit JSON files** in `src/lib/labels/`
471
508
  2. **Auto-sync happens** (if dev server is running)
472
509
  3. **Labels immediately available** via `getSection()` or `useSection()`
473
510
 
@@ -478,7 +515,7 @@ Available for both server and client components:
478
515
  pnpm dev
479
516
 
480
517
  # Terminal 2: Edit label file
481
- echo '{"test": {"key": "layout.test", "defaultValue": "Test"}}' > src/cms/labels/layout/test.json
518
+ echo '{"test": {"key": "layout.test", "defaultValue": "Test"}}' > src/lib/labels/layout/test.json
482
519
 
483
520
  # Auto-sync triggers
484
521
  # ✅ Label sync completed
@@ -0,0 +1,296 @@
1
+ /**
2
+ * Locale Constants
3
+ *
4
+ * Server/Client 양쪽에서 사용 가능한 locale 관련 상수
5
+ */
6
+ /**
7
+ * Locale 쿠키 키
8
+ */
9
+ declare const LOCALE_COOKIE_KEY = "spfn-locale";
10
+ /**
11
+ * 지원하는 Locale 타입 (Type-safe)
12
+ */
13
+ type SupportedLocale = 'ko' | 'ja' | 'zh' | 'zh-TW' | 'zh-HK' | 'hi' | 'th' | 'vi' | 'id' | 'ms' | 'en' | 'en-GB' | 'en-CA' | 'en-AU' | 'en-NZ' | 'es' | 'es-MX' | 'es-AR' | 'es-CO' | 'fr' | 'de' | 'it' | 'pt' | 'nl' | 'sv' | 'no' | 'da' | 'fi' | 'ru' | 'pl' | 'uk' | 'cs' | 'hu' | 'ro' | 'bg' | 'hr' | 'sr' | 'sk' | 'sl' | 'lt' | 'lv' | 'et' | 'el' | 'tr' | 'ar' | 'fa' | 'he' | 'sw';
14
+ /**
15
+ * 국가/지역 정보 타입
16
+ */
17
+ interface LocaleInfo {
18
+ /** Locale 코드 (ISO 639-1) */
19
+ locale: SupportedLocale;
20
+ /** 국가 코드 (ISO 3166-1 alpha-2) */
21
+ countryCode: string;
22
+ /** 국기 이모지 (HTML/React용) */
23
+ flag: string;
24
+ /** 전화번호 국가 코드 */
25
+ dialCode: string;
26
+ /** 네이티브 이름 (현지어) */
27
+ nativeName: string;
28
+ /** 영어 이름 */
29
+ englishName: string;
30
+ /** RTL (Right-to-Left) 여부 */
31
+ rtl?: boolean;
32
+ /** 통화 코드 (ISO 4217) */
33
+ currencyCode?: string;
34
+ /** 날짜 형식 예시 */
35
+ dateFormat?: string;
36
+ }
37
+ /**
38
+ * 사전 정의된 Locale 정보 맵
39
+ *
40
+ * 주요 언어/국가 정보를 포함합니다.
41
+ * 프로젝트에 맞게 추가/수정 가능합니다.
42
+ */
43
+ declare const LOCALE_INFO_MAP: Record<SupportedLocale, LocaleInfo>;
44
+ /**
45
+ * Locale 정보 가져오기
46
+ *
47
+ * @param locale - Locale 코드 (예: 'ko', 'en', 'ja')
48
+ * @returns LocaleInfo 또는 undefined
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const koInfo = getLocaleInfo('ko');
53
+ * console.log(koInfo.flag); // 🇰🇷
54
+ * console.log(koInfo.dialCode); // +82
55
+ * ```
56
+ */
57
+ declare function getLocaleInfo(locale: string): LocaleInfo | undefined;
58
+ /**
59
+ * 지원하는 모든 Locale 목록 가져오기
60
+ *
61
+ * @returns Locale 코드 배열
62
+ */
63
+ declare function getSupportedLocales(): SupportedLocale[];
64
+ /**
65
+ * 국기 이모지만 가져오기
66
+ *
67
+ * @param locale - Locale 코드
68
+ * @returns 국기 이모지 또는 빈 문자열
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * getFlag('ko'); // 🇰🇷
73
+ * getFlag('en'); // 🇺🇸
74
+ * ```
75
+ */
76
+ declare function getFlag(locale: string): string;
77
+ /**
78
+ * 전화번호 국가 코드 가져오기
79
+ *
80
+ * @param locale - Locale 코드
81
+ * @returns 전화번호 코드 또는 빈 문자열
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * getDialCode('ko'); // +82
86
+ * getDialCode('en'); // +1
87
+ * ```
88
+ */
89
+ declare function getDialCode(locale: string): string;
90
+ /**
91
+ * RTL (Right-to-Left) 여부 확인
92
+ *
93
+ * @param locale - Locale 코드
94
+ * @returns RTL 여부
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * isRTL('ar'); // true (Arabic)
99
+ * isRTL('ko'); // false (Korean)
100
+ * ```
101
+ */
102
+ declare function isRTL(locale: string): boolean;
103
+
104
+ /**
105
+ * 현재 locale 가져오기 (Server Action)
106
+ *
107
+ * 서버/클라이언트 컴포넌트 모두에서 사용 가능
108
+ *
109
+ * 우선순위:
110
+ * 1. 쿠키 (사용자가 명시적으로 선택한 언어)
111
+ * 2. 브라우저 언어 감지 (설정에서 활성화된 경우)
112
+ * 3. 시스템 기본 언어 (CMS 설정)
113
+ *
114
+ * @returns 현재 locale (예: 'ko', 'en')
115
+ *
116
+ * @example
117
+ * ```tsx
118
+ * // Server Component
119
+ * import { getLocale } from '@spfn/cms/actions';
120
+ *
121
+ * export default async function Page()
122
+ * {
123
+ * const locale = await getLocale();
124
+ * return <div>Current locale: {locale}</div>;
125
+ * }
126
+ * ```
127
+ *
128
+ * @example
129
+ * ```tsx
130
+ * // Client Component
131
+ * 'use client';
132
+ * import { getLocale } from '@spfn/cms/client';
133
+ *
134
+ * export default function LanguageSwitcher()
135
+ * {
136
+ * const [locale, setLocale] = useState('');
137
+ *
138
+ * useEffect(() => {
139
+ * getLocale().then(setLocale);
140
+ * }, []);
141
+ *
142
+ * return <div>Current locale: {locale}</div>;
143
+ * }
144
+ * ```
145
+ */
146
+ declare function getLocale(): Promise<string>;
147
+ /**
148
+ * Locale 설정하기 (Server Action)
149
+ *
150
+ * 서버/클라이언트 컴포넌트 모두에서 사용 가능
151
+ * 쿠키에 locale을 저장합니다.
152
+ *
153
+ * @param locale - 설정할 locale (예: 'ko', 'en')
154
+ * @throws {Error} 지원하지 않는 locale인 경우
155
+ *
156
+ * @example
157
+ * ```tsx
158
+ * // Server Component (Server Action)
159
+ * import { setLocale } from '@spfn/cms/actions';
160
+ *
161
+ * export default async function Page()
162
+ * {
163
+ * await setLocale('en');
164
+ * return <div>Locale changed</div>;
165
+ * }
166
+ * ```
167
+ *
168
+ * @example
169
+ * ```tsx
170
+ * // Client Component (Server Action)
171
+ * 'use client';
172
+ * import { setLocale } from '@spfn/cms/client';
173
+ *
174
+ * export default function LanguageSwitcher()
175
+ * {
176
+ * const handleChange = async (newLocale: string) =>
177
+ * {
178
+ * await setLocale(newLocale);
179
+ * window.location.reload(); // 페이지 새로고침
180
+ * };
181
+ *
182
+ * return (
183
+ * <button onClick={() => handleChange('en')}>
184
+ * Switch to English
185
+ * </button>
186
+ * );
187
+ * }
188
+ * ```
189
+ */
190
+ declare function setLocale(locale: string): Promise<void>;
191
+ /**
192
+ * 지원하는 locale 목록 가져오기 (Server Action)
193
+ *
194
+ * 서버/클라이언트 컴포넌트 모두에서 사용 가능
195
+ *
196
+ * @returns 지원하는 locale 배열 (예: ['ko', 'en', 'ja'])
197
+ *
198
+ * @example
199
+ * ```tsx
200
+ * // Server Component
201
+ * import { getLocales } from '@spfn/cms/actions';
202
+ *
203
+ * export default async function Page()
204
+ * {
205
+ * const locales = await getLocales();
206
+ * return <div>Supported: {locales.join(', ')}</div>;
207
+ * }
208
+ * ```
209
+ *
210
+ * @example
211
+ * ```tsx
212
+ * // Client Component
213
+ * 'use client';
214
+ * import { getLocales } from '@spfn/cms/client';
215
+ *
216
+ * export default function LanguageSwitcher()
217
+ * {
218
+ * const [locales, setLocales] = useState<string[]>([]);
219
+ *
220
+ * useEffect(() => {
221
+ * getLocales().then(setLocales);
222
+ * }, []);
223
+ *
224
+ * return (
225
+ * <div>
226
+ * {locales.map(locale => (
227
+ * <button key={locale}>{locale}</button>
228
+ * ))}
229
+ * </div>
230
+ * );
231
+ * }
232
+ * ```
233
+ */
234
+ declare function getLocales(): Promise<string[]>;
235
+ /**
236
+ * 현재 locale과 상세 정보 함께 가져오기 (Server Action)
237
+ *
238
+ * locale 코드와 함께 국가 코드, 국기, 전화번호 코드 등의 상세 정보를 반환합니다.
239
+ *
240
+ * @returns Locale 코드와 LocaleInfo 객체
241
+ *
242
+ * @example
243
+ * ```tsx
244
+ * // Server Component
245
+ * import { getLocaleWithInfo } from '@spfn/cms/actions';
246
+ *
247
+ * export default async function Page()
248
+ * {
249
+ * const { locale, info } = await getLocaleWithInfo();
250
+ *
251
+ * return (
252
+ * <div>
253
+ * <span>{info?.flag}</span>
254
+ * <span>{info?.nativeName}</span>
255
+ * <span>{info?.dialCode}</span>
256
+ * </div>
257
+ * );
258
+ * }
259
+ * ```
260
+ */
261
+ declare function getLocaleWithInfo(): Promise<{
262
+ locale: string;
263
+ info: LocaleInfo | undefined;
264
+ }>;
265
+ /**
266
+ * 지원하는 모든 locale과 상세 정보 가져오기 (Server Action)
267
+ *
268
+ * 시스템이 지원하는 모든 locale의 상세 정보를 배열로 반환합니다.
269
+ * 언어 선택 UI를 만들 때 유용합니다.
270
+ *
271
+ * @returns LocaleInfo 배열
272
+ *
273
+ * @example
274
+ * ```tsx
275
+ * // Server Component
276
+ * import { getLocalesWithInfo } from '@spfn/cms/actions';
277
+ *
278
+ * export default async function LanguageSelector()
279
+ * {
280
+ * const locales = await getLocalesWithInfo();
281
+ *
282
+ * return (
283
+ * <select>
284
+ * {locales.map(info => (
285
+ * <option key={info.locale} value={info.locale}>
286
+ * {info.flag} {info.nativeName}
287
+ * </option>
288
+ * ))}
289
+ * </select>
290
+ * );
291
+ * }
292
+ * ```
293
+ */
294
+ declare function getLocalesWithInfo(): Promise<LocaleInfo[]>;
295
+
296
+ export { LOCALE_COOKIE_KEY as L, type SupportedLocale as S, getSupportedLocales as a, getFlag as b, getDialCode as c, LOCALE_INFO_MAP as d, type LocaleInfo as e, getLocale as f, getLocaleInfo as g, getLocales as h, isRTL as i, getLocaleWithInfo as j, getLocalesWithInfo as k, setLocale as s };
package/dist/actions.d.ts CHANGED
@@ -1,143 +1 @@
1
- /**
2
- * 현재 locale 가져오기 (Server Action)
3
- *
4
- * 서버/클라이언트 컴포넌트 모두에서 사용 가능
5
- *
6
- * 우선순위:
7
- * 1. 쿠키 (사용자가 명시적으로 선택한 언어)
8
- * 2. 브라우저 언어 감지 (설정에서 활성화된 경우)
9
- * 3. 시스템 기본 언어 (CMS 설정)
10
- *
11
- * @returns 현재 locale (예: 'ko', 'en')
12
- *
13
- * @example
14
- * ```tsx
15
- * // Server Component
16
- * import { getLocale } from '@spfn/cms';
17
- *
18
- * export default async function Page()
19
- * {
20
- * const locale = await getLocale();
21
- * return <div>Current locale: {locale}</div>;
22
- * }
23
- * ```
24
- *
25
- * @example
26
- * ```tsx
27
- * // Client Component
28
- * 'use client';
29
- * import { getLocale } from '@spfn/cms/client';
30
- *
31
- * export default function LanguageSwitcher()
32
- * {
33
- * const [locale, setLocale] = useState('');
34
- *
35
- * useEffect(() => {
36
- * getLocale().then(setLocale);
37
- * }, []);
38
- *
39
- * return <div>Current locale: {locale}</div>;
40
- * }
41
- * ```
42
- */
43
- declare function getLocale(): Promise<string>;
44
- /**
45
- * Locale 설정하기 (Server Action)
46
- *
47
- * 서버/클라이언트 컴포넌트 모두에서 사용 가능
48
- * 쿠키에 locale을 저장합니다.
49
- *
50
- * @param locale - 설정할 locale (예: 'ko', 'en')
51
- * @throws {Error} 지원하지 않는 locale인 경우
52
- *
53
- * @example
54
- * ```tsx
55
- * // Server Component (Server Action)
56
- * import { setLocale } from '@spfn/cms';
57
- *
58
- * export default async function Page()
59
- * {
60
- * await setLocale('en');
61
- * return <div>Locale changed</div>;
62
- * }
63
- * ```
64
- *
65
- * @example
66
- * ```tsx
67
- * // Client Component (Server Action)
68
- * 'use client';
69
- * import { setLocale } from '@spfn/cms/client';
70
- *
71
- * export default function LanguageSwitcher()
72
- * {
73
- * const handleChange = async (newLocale: string) =>
74
- * {
75
- * await setLocale(newLocale);
76
- * window.location.reload(); // 페이지 새로고침
77
- * };
78
- *
79
- * return (
80
- * <button onClick={() => handleChange('en')}>
81
- * Switch to English
82
- * </button>
83
- * );
84
- * }
85
- * ```
86
- */
87
- declare function setLocale(locale: string): Promise<void>;
88
- /**
89
- * 지원하는 locale 목록 가져오기 (Server Action)
90
- *
91
- * 서버/클라이언트 컴포넌트 모두에서 사용 가능
92
- *
93
- * @returns 지원하는 locale 배열 (예: ['ko', 'en', 'ja'])
94
- *
95
- * @example
96
- * ```tsx
97
- * // Server Component
98
- * import { getLocales } from '@spfn/cms';
99
- *
100
- * export default async function Page()
101
- * {
102
- * const locales = await getLocales();
103
- * return <div>Supported: {locales.join(', ')}</div>;
104
- * }
105
- * ```
106
- *
107
- * @example
108
- * ```tsx
109
- * // Client Component
110
- * 'use client';
111
- * import { getLocales } from '@spfn/cms/client';
112
- *
113
- * export default function LanguageSwitcher()
114
- * {
115
- * const [locales, setLocales] = useState<string[]>([]);
116
- *
117
- * useEffect(() => {
118
- * getLocales().then(setLocales);
119
- * }, []);
120
- *
121
- * return (
122
- * <div>
123
- * {locales.map(locale => (
124
- * <button key={locale}>{locale}</button>
125
- * ))}
126
- * </div>
127
- * );
128
- * }
129
- * ```
130
- */
131
- declare function getLocales(): Promise<string[]>;
132
-
133
- /**
134
- * Locale Constants
135
- *
136
- * Server/Client 양쪽에서 사용 가능한 locale 관련 상수
137
- */
138
- /**
139
- * Locale 쿠키 키
140
- */
141
- declare const LOCALE_COOKIE_KEY = "spfn-locale";
142
-
143
- export { LOCALE_COOKIE_KEY, getLocale, getLocales, setLocale };
1
+ export { L as LOCALE_COOKIE_KEY, f as getLocale, h as getLocales, s as setLocale } from './actions-CwvmPG0e.js';
package/dist/actions.js CHANGED
@@ -1,7 +1,7 @@
1
- // src/helpers/locale.actions.ts
2
- import { cookies, headers } from "next/headers.js";
1
+ // src/server/helpers/locale.actions.ts
2
+ import { cookies, headers } from "next/headers";
3
3
 
4
- // src/cms.config.ts
4
+ // src/server/config/cms.config.ts
5
5
  function getEnvVar(key, defaultValue) {
6
6
  return process.env[key] || defaultValue;
7
7
  }
@@ -29,10 +29,10 @@ function getCmsConfig() {
29
29
  return currentConfig;
30
30
  }
31
31
 
32
- // src/helpers/locale.constants.ts
32
+ // src/lib/constants/locale.constants.ts
33
33
  var LOCALE_COOKIE_KEY = "spfn-locale";
34
34
 
35
- // src/helpers/locale.actions.ts
35
+ // src/server/helpers/locale.actions.ts
36
36
  async function detectBrowserLanguage() {
37
37
  try {
38
38
  const headersList = await headers();