@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.
- package/README.md +67 -30
- package/dist/actions-CwvmPG0e.d.ts +296 -0
- package/dist/actions.d.ts +1 -143
- package/dist/actions.js +5 -5
- package/dist/actions.js.map +1 -1
- package/dist/api.d.ts +376 -0
- package/dist/api.js +364 -0
- package/dist/api.js.map +1 -0
- package/dist/client.d.ts +115 -141
- package/dist/client.js +860 -63
- package/dist/client.js.map +1 -1
- package/dist/{types.d.ts → index-Dh5FjWzR.d.ts} +32 -1
- package/dist/index.d.ts +21 -43
- package/dist/index.js +556 -1061
- package/dist/index.js.map +1 -1
- package/dist/label-sync-generator-B0EmvtWM.d.ts +32 -0
- package/dist/{contracts → lib/contracts}/labels.d.ts +13 -12
- package/dist/{contracts → lib/contracts}/labels.js +7 -7
- package/dist/lib/contracts/labels.js.map +1 -0
- package/dist/{contracts → lib/contracts}/published-cache.d.ts +3 -2
- package/dist/{contracts → lib/contracts}/published-cache.js +2 -2
- package/dist/lib/contracts/published-cache.js.map +1 -0
- package/dist/{contracts → lib/contracts}/values.d.ts +6 -4
- package/dist/{contracts → lib/contracts}/values.js +3 -3
- package/dist/lib/contracts/values.js.map +1 -0
- package/dist/{entities → server/entities}/cms-audit-logs.js +3 -3
- package/dist/server/entities/cms-audit-logs.js.map +1 -0
- package/dist/{entities → server/entities}/cms-draft-cache.js +1 -1
- package/dist/server/entities/cms-draft-cache.js.map +1 -0
- package/dist/{entities → server/entities}/cms-label-values.js +3 -3
- package/dist/server/entities/cms-label-values.js.map +1 -0
- package/dist/{entities → server/entities}/cms-label-versions.js +3 -3
- package/dist/server/entities/cms-label-versions.js.map +1 -0
- package/dist/{entities → server/entities}/cms-labels.js +1 -1
- package/dist/server/entities/cms-labels.js.map +1 -0
- package/dist/{entities → server/entities}/cms-published-cache.js +1 -1
- package/dist/server/entities/cms-published-cache.js.map +1 -0
- package/dist/{entities → server/entities}/index.js +6 -6
- package/dist/server/entities/index.js.map +1 -0
- package/dist/{generators → server/generators}/index.d.ts +1 -2
- package/dist/{generators → server/generators}/index.js +169 -75
- package/dist/server/generators/index.js.map +1 -0
- package/dist/server/labels/index.d.ts +1 -0
- package/dist/{labels → server/labels}/index.js +1 -1
- package/dist/server/labels/index.js.map +1 -0
- package/dist/{repositories → server/repositories}/index.js +11 -11
- package/dist/server/repositories/index.js.map +1 -0
- package/dist/{routes → server/routes}/labels/[id]/index.js +20 -20
- package/dist/server/routes/labels/[id]/index.js.map +1 -0
- package/dist/{routes → server/routes}/labels/by-key/[key]/index.js +20 -20
- package/dist/server/routes/labels/by-key/[key]/index.js.map +1 -0
- package/dist/{routes → server/routes}/labels/index.d.ts +2 -2
- package/dist/{routes → server/routes}/labels/index.js +21 -22
- package/dist/server/routes/labels/index.js.map +1 -0
- package/dist/{routes → server/routes}/published-cache/index.js +14 -14
- package/dist/server/routes/published-cache/index.js.map +1 -0
- package/dist/{routes → server/routes}/values/[labelId]/[version]/index.js +16 -16
- package/dist/server/routes/values/[labelId]/[version]/index.js.map +1 -0
- package/dist/{routes → server/routes}/values/[labelId]/index.js +16 -16
- package/dist/server/routes/values/[labelId]/index.js.map +1 -0
- package/dist/server.d.ts +76 -7
- package/dist/server.js +1601 -42
- package/dist/server.js.map +1 -1
- package/package.json +37 -35
- package/dist/contracts/labels.js.map +0 -1
- package/dist/contracts/published-cache.js.map +0 -1
- package/dist/contracts/values.js.map +0 -1
- package/dist/entities/cms-audit-logs.js.map +0 -1
- package/dist/entities/cms-draft-cache.js.map +0 -1
- package/dist/entities/cms-label-values.js.map +0 -1
- package/dist/entities/cms-label-versions.js.map +0 -1
- package/dist/entities/cms-labels.js.map +0 -1
- package/dist/entities/cms-published-cache.js.map +0 -1
- package/dist/entities/index.js.map +0 -1
- package/dist/generators/index.js.map +0 -1
- package/dist/label-sync-generator-lQrcVfja.d.ts +0 -36
- package/dist/labels/index.d.ts +0 -34
- package/dist/labels/index.js.map +0 -1
- package/dist/repositories/index.js.map +0 -1
- package/dist/routes/labels/[id]/index.js.map +0 -1
- package/dist/routes/labels/by-key/[key]/index.js.map +0 -1
- package/dist/routes/labels/index.js.map +0 -1
- package/dist/routes/published-cache/index.js.map +0 -1
- package/dist/routes/values/[labelId]/[version]/index.js.map +0 -1
- package/dist/routes/values/[labelId]/index.js.map +0 -1
- package/dist/store.d.ts +0 -81
- package/dist/store.js +0 -403
- package/dist/store.js.map +0 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +0 -1
- package/dist/{entities → server/entities}/cms-audit-logs.d.ts +0 -0
- package/dist/{entities → server/entities}/cms-draft-cache.d.ts +0 -0
- package/dist/{entities → server/entities}/cms-label-values.d.ts +0 -0
- package/dist/{entities → server/entities}/cms-label-versions.d.ts +0 -0
- package/dist/{entities → server/entities}/cms-labels.d.ts +0 -0
- package/dist/{entities → server/entities}/cms-published-cache.d.ts +0 -0
- package/dist/{entities → server/entities}/index.d.ts +0 -0
- package/dist/{repositories → server/repositories}/index.d.ts +14 -14
- /package/dist/{routes → server/routes}/labels/_id_/index.d.ts +0 -0
- /package/dist/{routes → server/routes}/labels/by-key/_key_/index.d.ts +0 -0
- /package/dist/{routes → server/routes}/published-cache/index.d.ts +0 -0
- /package/dist/{routes → server/routes}/values/_labelId_/_version_/index.d.ts +0 -0
- /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
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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:
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
-
###
|
|
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
|
-
|
|
468
|
+
**Repositories & Entities:**
|
|
469
|
+
- All repository and entity exports
|
|
435
470
|
|
|
436
|
-
|
|
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
|
-
- `
|
|
479
|
+
- `getLocaleWithInfo()`, `getLocalesWithInfo()`, `isValidLocale()`
|
|
442
480
|
|
|
443
|
-
###
|
|
481
|
+
### Server Actions API (`@spfn/cms/actions`)
|
|
444
482
|
|
|
445
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
494
|
+
⚠️ **Admin only** - Use with proper authentication
|
|
464
495
|
|
|
465
|
-
- `
|
|
466
|
-
- `
|
|
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/
|
|
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/
|
|
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
|
|
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/
|
|
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();
|