@spfn/cms 0.1.0-alpha.9 → 0.2.0-beta.2

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 (171) hide show
  1. package/README.md +320 -359
  2. package/dist/actions.d.ts +12 -6
  3. package/dist/actions.js +25 -10
  4. package/dist/actions.js.map +1 -1
  5. package/dist/config.d.ts +39 -0
  6. package/dist/config.js +39 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/errors.d.ts +149 -0
  9. package/dist/errors.js +164 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/index.d.ts +138 -20
  12. package/dist/index.js +212 -23
  13. package/dist/index.js.map +1 -1
  14. package/dist/server.d.ts +44 -81
  15. package/dist/server.js +610 -256
  16. package/dist/server.js.map +1 -1
  17. package/migrations/0000_medical_ozymandias.sql +54 -0
  18. package/migrations/meta/0000_snapshot.json +336 -0
  19. package/migrations/meta/_journal.json +13 -0
  20. package/package.json +54 -44
  21. package/dist/actions.d.ts.map +0 -1
  22. package/dist/client.d.ts +0 -138
  23. package/dist/client.d.ts.map +0 -1
  24. package/dist/client.js +0 -62
  25. package/dist/client.js.map +0 -1
  26. package/dist/cms.config.d.ts +0 -77
  27. package/dist/cms.config.d.ts.map +0 -1
  28. package/dist/cms.config.js +0 -111
  29. package/dist/cms.config.js.map +0 -1
  30. package/dist/entities/cms-audit-logs.d.ts +0 -213
  31. package/dist/entities/cms-audit-logs.d.ts.map +0 -1
  32. package/dist/entities/cms-audit-logs.js +0 -103
  33. package/dist/entities/cms-audit-logs.js.map +0 -1
  34. package/dist/entities/cms-draft-cache.d.ts +0 -188
  35. package/dist/entities/cms-draft-cache.d.ts.map +0 -1
  36. package/dist/entities/cms-draft-cache.js +0 -112
  37. package/dist/entities/cms-draft-cache.js.map +0 -1
  38. package/dist/entities/cms-label-values.d.ts +0 -192
  39. package/dist/entities/cms-label-values.d.ts.map +0 -1
  40. package/dist/entities/cms-label-values.js +0 -105
  41. package/dist/entities/cms-label-values.js.map +0 -1
  42. package/dist/entities/cms-label-versions.d.ts +0 -207
  43. package/dist/entities/cms-label-versions.d.ts.map +0 -1
  44. package/dist/entities/cms-label-versions.js +0 -80
  45. package/dist/entities/cms-label-versions.js.map +0 -1
  46. package/dist/entities/cms-labels.d.ts +0 -189
  47. package/dist/entities/cms-labels.d.ts.map +0 -1
  48. package/dist/entities/cms-labels.js +0 -48
  49. package/dist/entities/cms-labels.js.map +0 -1
  50. package/dist/entities/cms-published-cache.d.ts +0 -199
  51. package/dist/entities/cms-published-cache.d.ts.map +0 -1
  52. package/dist/entities/cms-published-cache.js +0 -103
  53. package/dist/entities/cms-published-cache.js.map +0 -1
  54. package/dist/entities/index.d.ts +0 -10
  55. package/dist/entities/index.d.ts.map +0 -1
  56. package/dist/entities/index.js +0 -10
  57. package/dist/entities/index.js.map +0 -1
  58. package/dist/generators/index.d.ts +0 -19
  59. package/dist/generators/index.d.ts.map +0 -1
  60. package/dist/generators/index.js +0 -19
  61. package/dist/generators/index.js.map +0 -1
  62. package/dist/generators/label-sync-generator.d.ts +0 -33
  63. package/dist/generators/label-sync-generator.d.ts.map +0 -1
  64. package/dist/generators/label-sync-generator.js +0 -86
  65. package/dist/generators/label-sync-generator.js.map +0 -1
  66. package/dist/helpers/locale.actions.d.ts +0 -132
  67. package/dist/helpers/locale.actions.d.ts.map +0 -1
  68. package/dist/helpers/locale.actions.js +0 -210
  69. package/dist/helpers/locale.actions.js.map +0 -1
  70. package/dist/helpers/locale.constants.d.ts +0 -10
  71. package/dist/helpers/locale.constants.d.ts.map +0 -1
  72. package/dist/helpers/locale.constants.js +0 -10
  73. package/dist/helpers/locale.constants.js.map +0 -1
  74. package/dist/helpers/locale.d.ts +0 -17
  75. package/dist/helpers/locale.d.ts.map +0 -1
  76. package/dist/helpers/locale.js +0 -20
  77. package/dist/helpers/locale.js.map +0 -1
  78. package/dist/helpers/sync.d.ts +0 -41
  79. package/dist/helpers/sync.d.ts.map +0 -1
  80. package/dist/helpers/sync.js +0 -309
  81. package/dist/helpers/sync.js.map +0 -1
  82. package/dist/index.d.ts.map +0 -1
  83. package/dist/init.d.ts +0 -31
  84. package/dist/init.d.ts.map +0 -1
  85. package/dist/init.js +0 -36
  86. package/dist/init.js.map +0 -1
  87. package/dist/labels/helpers.d.ts +0 -31
  88. package/dist/labels/helpers.d.ts.map +0 -1
  89. package/dist/labels/helpers.js +0 -60
  90. package/dist/labels/helpers.js.map +0 -1
  91. package/dist/labels/index.d.ts +0 -7
  92. package/dist/labels/index.d.ts.map +0 -1
  93. package/dist/labels/index.js +0 -7
  94. package/dist/labels/index.js.map +0 -1
  95. package/dist/repositories/cms-draft-cache.repository.d.ts +0 -62
  96. package/dist/repositories/cms-draft-cache.repository.d.ts.map +0 -1
  97. package/dist/repositories/cms-draft-cache.repository.js +0 -56
  98. package/dist/repositories/cms-draft-cache.repository.js.map +0 -1
  99. package/dist/repositories/cms-label-values.repository.d.ts +0 -32
  100. package/dist/repositories/cms-label-values.repository.d.ts.map +0 -1
  101. package/dist/repositories/cms-label-values.repository.js +0 -72
  102. package/dist/repositories/cms-label-values.repository.js.map +0 -1
  103. package/dist/repositories/cms-labels.repository.d.ts +0 -53
  104. package/dist/repositories/cms-labels.repository.d.ts.map +0 -1
  105. package/dist/repositories/cms-labels.repository.js +0 -77
  106. package/dist/repositories/cms-labels.repository.js.map +0 -1
  107. package/dist/repositories/cms-published-cache.repository.d.ts +0 -53
  108. package/dist/repositories/cms-published-cache.repository.d.ts.map +0 -1
  109. package/dist/repositories/cms-published-cache.repository.js +0 -54
  110. package/dist/repositories/cms-published-cache.repository.js.map +0 -1
  111. package/dist/repositories/index.d.ts +0 -8
  112. package/dist/repositories/index.d.ts.map +0 -1
  113. package/dist/repositories/index.js +0 -9
  114. package/dist/repositories/index.js.map +0 -1
  115. package/dist/routes/labels/[id]/contract.d.ts +0 -68
  116. package/dist/routes/labels/[id]/contract.d.ts.map +0 -1
  117. package/dist/routes/labels/[id]/contract.js +0 -84
  118. package/dist/routes/labels/[id]/contract.js.map +0 -1
  119. package/dist/routes/labels/[id]/index.d.ts +0 -10
  120. package/dist/routes/labels/[id]/index.d.ts.map +0 -1
  121. package/dist/routes/labels/[id]/index.js +0 -96
  122. package/dist/routes/labels/[id]/index.js.map +0 -1
  123. package/dist/routes/labels/by-key/[key]/contract.d.ts +0 -24
  124. package/dist/routes/labels/by-key/[key]/contract.d.ts.map +0 -1
  125. package/dist/routes/labels/by-key/[key]/contract.js +0 -28
  126. package/dist/routes/labels/by-key/[key]/contract.js.map +0 -1
  127. package/dist/routes/labels/by-key/[key]/index.d.ts +0 -8
  128. package/dist/routes/labels/by-key/[key]/index.d.ts.map +0 -1
  129. package/dist/routes/labels/by-key/[key]/index.js +0 -32
  130. package/dist/routes/labels/by-key/[key]/index.js.map +0 -1
  131. package/dist/routes/labels/contract.d.ts +0 -59
  132. package/dist/routes/labels/contract.d.ts.map +0 -1
  133. package/dist/routes/labels/contract.js +0 -75
  134. package/dist/routes/labels/contract.js.map +0 -1
  135. package/dist/routes/labels/index.d.ts +0 -10
  136. package/dist/routes/labels/index.d.ts.map +0 -1
  137. package/dist/routes/labels/index.js +0 -73
  138. package/dist/routes/labels/index.js.map +0 -1
  139. package/dist/routes/published-cache/contract.d.ts +0 -25
  140. package/dist/routes/published-cache/contract.d.ts.map +0 -1
  141. package/dist/routes/published-cache/contract.js +0 -35
  142. package/dist/routes/published-cache/contract.js.map +0 -1
  143. package/dist/routes/published-cache/index.d.ts +0 -8
  144. package/dist/routes/published-cache/index.d.ts.map +0 -1
  145. package/dist/routes/published-cache/index.js +0 -33
  146. package/dist/routes/published-cache/index.js.map +0 -1
  147. package/dist/routes/values/[labelId]/[version]/contract.d.ts +0 -29
  148. package/dist/routes/values/[labelId]/[version]/contract.d.ts.map +0 -1
  149. package/dist/routes/values/[labelId]/[version]/contract.js +0 -33
  150. package/dist/routes/values/[labelId]/[version]/contract.js.map +0 -1
  151. package/dist/routes/values/[labelId]/[version]/index.d.ts +0 -8
  152. package/dist/routes/values/[labelId]/[version]/index.d.ts.map +0 -1
  153. package/dist/routes/values/[labelId]/[version]/index.js +0 -45
  154. package/dist/routes/values/[labelId]/[version]/index.js.map +0 -1
  155. package/dist/routes/values/[labelId]/contract.d.ts +0 -38
  156. package/dist/routes/values/[labelId]/contract.d.ts.map +0 -1
  157. package/dist/routes/values/[labelId]/contract.js +0 -59
  158. package/dist/routes/values/[labelId]/contract.js.map +0 -1
  159. package/dist/routes/values/[labelId]/index.d.ts +0 -8
  160. package/dist/routes/values/[labelId]/index.d.ts.map +0 -1
  161. package/dist/routes/values/[labelId]/index.js +0 -42
  162. package/dist/routes/values/[labelId]/index.js.map +0 -1
  163. package/dist/server.d.ts.map +0 -1
  164. package/dist/store.d.ts +0 -87
  165. package/dist/store.d.ts.map +0 -1
  166. package/dist/store.js +0 -205
  167. package/dist/store.js.map +0 -1
  168. package/dist/types.d.ts +0 -74
  169. package/dist/types.d.ts.map +0 -1
  170. package/dist/types.js +0 -7
  171. package/dist/types.js.map +0 -1
@@ -1,86 +0,0 @@
1
- /**
2
- * Label Sync Generator
3
- *
4
- * File-based label sync with JSON definitions
5
- *
6
- * Structure:
7
- * cms/labels/
8
- * layout/ # Section name
9
- * nav.json # Label definitions
10
- * footer.json
11
- * homepage/
12
- * hero.json
13
- */
14
- import { logger } from '@spfn/core';
15
- import { join } from 'path';
16
- import { syncAll, loadLabelsFromJson } from '../helpers/sync.js';
17
- const syncLogger = logger.child('label-sync');
18
- export class LabelSyncGenerator {
19
- name = 'label-sync';
20
- labelsDir;
21
- constructor(config = {}) {
22
- this.labelsDir = config.labelsDir ?? 'src/cms/labels';
23
- }
24
- /**
25
- * Watch patterns for label definition files
26
- */
27
- get watchPatterns() {
28
- return [
29
- `${this.labelsDir}/**/*.json`,
30
- ];
31
- }
32
- async generate(options) {
33
- if (options.debug) {
34
- syncLogger.info('Starting label sync...');
35
- }
36
- try {
37
- const labelsPath = join(options.cwd, this.labelsDir);
38
- // Load labels from JSON files
39
- const sections = loadLabelsFromJson(labelsPath);
40
- if (sections.length === 0) {
41
- syncLogger.warn(`No labels found in ${labelsPath}`);
42
- return;
43
- }
44
- syncLogger.info(`Found ${sections.length} sections`);
45
- // Sync all sections
46
- const results = await syncAll(sections, {
47
- verbose: options.debug ?? false,
48
- updateExisting: true, // 항상 업데이트 (프로덕션 포함)
49
- });
50
- const totalCreated = results.reduce((sum, r) => sum + r.created, 0);
51
- const totalUpdated = results.reduce((sum, r) => sum + r.updated, 0);
52
- const totalErrors = results.reduce((sum, r) => sum + r.errors.length, 0);
53
- if (options.debug || totalCreated > 0 || totalUpdated > 0) {
54
- syncLogger.info('Label sync completed', {
55
- sections: results.length,
56
- created: totalCreated,
57
- updated: totalUpdated,
58
- errors: totalErrors,
59
- });
60
- }
61
- // Log errors if any
62
- if (totalErrors > 0) {
63
- results.forEach((result) => {
64
- result.errors.forEach((error) => {
65
- syncLogger.error(`[${result.section}] ${error.key}: ${error.error}`);
66
- });
67
- });
68
- }
69
- }
70
- catch (error) {
71
- syncLogger.error('Label sync failed', error instanceof Error ? error : new Error(String(error)));
72
- }
73
- }
74
- async onFileChange(filePath, event) {
75
- syncLogger.info(`Label file ${event}`, { file: filePath });
76
- // Re-sync all labels when any label file changes
77
- await this.generate({ cwd: process.cwd(), debug: true });
78
- }
79
- }
80
- /**
81
- * Create label sync generator instance
82
- */
83
- export function createLabelSyncGenerator(config) {
84
- return new LabelSyncGenerator(config);
85
- }
86
- //# sourceMappingURL=label-sync-generator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"label-sync-generator.js","sourceRoot":"","sources":["../../src/generators/label-sync-generator.ts"],"names":[],"mappings":"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"}
@@ -1,132 +0,0 @@
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
- export 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
- export 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
- export declare function getLocales(): Promise<string[]>;
132
- //# sourceMappingURL=locale.actions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale.actions.d.ts","sourceRoot":"","sources":["../../src/helpers/locale.actions.ts"],"names":[],"mappings":"AA8DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAyBjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAIpD"}
@@ -1,210 +0,0 @@
1
- "use server";
2
- /**
3
- * Locale Management Server Actions
4
- *
5
- * Server Actions으로 구현된 locale 관리 함수
6
- * - 서버 컴포넌트: 일반 함수 호출로 동작
7
- * - 클라이언트 컴포넌트: Server Action으로 자동 처리
8
- */
9
- import { cookies, headers } from 'next/headers';
10
- import { getCmsConfig } from '../cms.config.js';
11
- import { LOCALE_COOKIE_KEY } from './locale.constants.js';
12
- /**
13
- * 브라우저 언어 감지
14
- *
15
- * Accept-Language 헤더에서 지원하는 언어를 찾습니다.
16
- *
17
- * @returns 감지된 언어 코드 또는 null
18
- */
19
- async function detectBrowserLanguage() {
20
- try {
21
- const headersList = await headers();
22
- const acceptLanguage = headersList.get('accept-language');
23
- if (!acceptLanguage) {
24
- return null;
25
- }
26
- // "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7" 형식 파싱
27
- const languages = acceptLanguage
28
- .split(',')
29
- .map(lang => {
30
- const [code] = lang.split(';');
31
- return code.split('-')[0].trim();
32
- });
33
- const config = getCmsConfig();
34
- // 지원하는 언어 중 첫 번째 매칭되는 언어 반환
35
- for (const lang of languages) {
36
- if (config.supportedLocales.includes(lang)) {
37
- return lang;
38
- }
39
- }
40
- return null;
41
- }
42
- catch (error) {
43
- // 헤더 접근 실패 시
44
- return null;
45
- }
46
- }
47
- /**
48
- * 현재 locale 가져오기 (Server Action)
49
- *
50
- * 서버/클라이언트 컴포넌트 모두에서 사용 가능
51
- *
52
- * 우선순위:
53
- * 1. 쿠키 (사용자가 명시적으로 선택한 언어)
54
- * 2. 브라우저 언어 감지 (설정에서 활성화된 경우)
55
- * 3. 시스템 기본 언어 (CMS 설정)
56
- *
57
- * @returns 현재 locale (예: 'ko', 'en')
58
- *
59
- * @example
60
- * ```tsx
61
- * // Server Component
62
- * import { getLocale } from '@spfn/cms';
63
- *
64
- * export default async function Page()
65
- * {
66
- * const locale = await getLocale();
67
- * return <div>Current locale: {locale}</div>;
68
- * }
69
- * ```
70
- *
71
- * @example
72
- * ```tsx
73
- * // Client Component
74
- * 'use client';
75
- * import { getLocale } from '@spfn/cms/client';
76
- *
77
- * export default function LanguageSwitcher()
78
- * {
79
- * const [locale, setLocale] = useState('');
80
- *
81
- * useEffect(() => {
82
- * getLocale().then(setLocale);
83
- * }, []);
84
- *
85
- * return <div>Current locale: {locale}</div>;
86
- * }
87
- * ```
88
- */
89
- export async function getLocale() {
90
- const config = getCmsConfig();
91
- // 1순위: 쿠키 (사용자가 명시적으로 선택한 언어)
92
- const cookieStore = await cookies();
93
- const cookieLocale = cookieStore.get(LOCALE_COOKIE_KEY)?.value;
94
- if (cookieLocale && config.supportedLocales.includes(cookieLocale)) {
95
- return cookieLocale;
96
- }
97
- // 2순위: 브라우저 언어 감지 (설정에서 활성화된 경우)
98
- if (config.detectBrowserLanguage) {
99
- const browserLang = await detectBrowserLanguage();
100
- if (browserLang) {
101
- return browserLang;
102
- }
103
- }
104
- // 3순위: 시스템 기본 언어
105
- return config.defaultLocale;
106
- }
107
- /**
108
- * Locale 설정하기 (Server Action)
109
- *
110
- * 서버/클라이언트 컴포넌트 모두에서 사용 가능
111
- * 쿠키에 locale을 저장합니다.
112
- *
113
- * @param locale - 설정할 locale (예: 'ko', 'en')
114
- * @throws {Error} 지원하지 않는 locale인 경우
115
- *
116
- * @example
117
- * ```tsx
118
- * // Server Component (Server Action)
119
- * import { setLocale } from '@spfn/cms';
120
- *
121
- * export default async function Page()
122
- * {
123
- * await setLocale('en');
124
- * return <div>Locale changed</div>;
125
- * }
126
- * ```
127
- *
128
- * @example
129
- * ```tsx
130
- * // Client Component (Server Action)
131
- * 'use client';
132
- * import { setLocale } from '@spfn/cms/client';
133
- *
134
- * export default function LanguageSwitcher()
135
- * {
136
- * const handleChange = async (newLocale: string) =>
137
- * {
138
- * await setLocale(newLocale);
139
- * window.location.reload(); // 페이지 새로고침
140
- * };
141
- *
142
- * return (
143
- * <button onClick={() => handleChange('en')}>
144
- * Switch to English
145
- * </button>
146
- * );
147
- * }
148
- * ```
149
- */
150
- export async function setLocale(locale) {
151
- const config = getCmsConfig();
152
- // 유효성 검사
153
- if (!config.supportedLocales.includes(locale)) {
154
- throw new Error(`Unsupported locale: ${locale}. Supported locales: ${config.supportedLocales.join(', ')}`);
155
- }
156
- const cookieStore = await cookies();
157
- cookieStore.set(LOCALE_COOKIE_KEY, locale, {
158
- path: '/',
159
- maxAge: 60 * 60 * 24 * 365, // 1년
160
- sameSite: 'lax',
161
- });
162
- }
163
- /**
164
- * 지원하는 locale 목록 가져오기 (Server Action)
165
- *
166
- * 서버/클라이언트 컴포넌트 모두에서 사용 가능
167
- *
168
- * @returns 지원하는 locale 배열 (예: ['ko', 'en', 'ja'])
169
- *
170
- * @example
171
- * ```tsx
172
- * // Server Component
173
- * import { getLocales } from '@spfn/cms';
174
- *
175
- * export default async function Page()
176
- * {
177
- * const locales = await getLocales();
178
- * return <div>Supported: {locales.join(', ')}</div>;
179
- * }
180
- * ```
181
- *
182
- * @example
183
- * ```tsx
184
- * // Client Component
185
- * 'use client';
186
- * import { getLocales } from '@spfn/cms/client';
187
- *
188
- * export default function LanguageSwitcher()
189
- * {
190
- * const [locales, setLocales] = useState<string[]>([]);
191
- *
192
- * useEffect(() => {
193
- * getLocales().then(setLocales);
194
- * }, []);
195
- *
196
- * return (
197
- * <div>
198
- * {locales.map(locale => (
199
- * <button key={locale}>{locale}</button>
200
- * ))}
201
- * </div>
202
- * );
203
- * }
204
- * ```
205
- */
206
- export async function getLocales() {
207
- const config = getCmsConfig();
208
- return config.supportedLocales;
209
- }
210
- //# sourceMappingURL=locale.actions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale.actions.js","sourceRoot":"","sources":["../../src/helpers/locale.actions.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- /**
2
- * Locale Constants
3
- *
4
- * Server/Client 양쪽에서 사용 가능한 locale 관련 상수
5
- */
6
- /**
7
- * Locale 쿠키 키
8
- */
9
- export declare const LOCALE_COOKIE_KEY = "spfn-locale";
10
- //# sourceMappingURL=locale.constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale.constants.d.ts","sourceRoot":"","sources":["../../src/helpers/locale.constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,gBAAgB,CAAC"}
@@ -1,10 +0,0 @@
1
- /**
2
- * Locale Constants
3
- *
4
- * Server/Client 양쪽에서 사용 가능한 locale 관련 상수
5
- */
6
- /**
7
- * Locale 쿠키 키
8
- */
9
- export const LOCALE_COOKIE_KEY = 'spfn-locale';
10
- //# sourceMappingURL=locale.constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale.constants.js","sourceRoot":"","sources":["../../src/helpers/locale.constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC"}
@@ -1,17 +0,0 @@
1
- import "server-only";
2
- /**
3
- * Locale Management Module (Server Components)
4
- *
5
- * 서버 컴포넌트용 locale 관리 (Server Actions re-export)
6
- * 실제 구현은 locale.actions.ts 참조
7
- */
8
- export { getLocale, setLocale, getLocales, } from './locale.actions.js';
9
- export { LOCALE_COOKIE_KEY } from './locale.constants.js';
10
- /**
11
- * Locale 유효성 검사
12
- *
13
- * @param locale - 검사할 locale
14
- * @returns 지원 여부
15
- */
16
- export declare function isValidLocale(locale: string): Promise<boolean>;
17
- //# sourceMappingURL=locale.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/helpers/locale.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB;;;;;GAKG;AAEH,OAAO,EACH,SAAS,EACT,SAAS,EACT,UAAU,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAIpE"}
@@ -1,20 +0,0 @@
1
- import "server-only";
2
- /**
3
- * Locale Management Module (Server Components)
4
- *
5
- * 서버 컴포넌트용 locale 관리 (Server Actions re-export)
6
- * 실제 구현은 locale.actions.ts 참조
7
- */
8
- export { getLocale, setLocale, getLocales, } from './locale.actions.js';
9
- export { LOCALE_COOKIE_KEY } from './locale.constants.js';
10
- /**
11
- * Locale 유효성 검사
12
- *
13
- * @param locale - 검사할 locale
14
- * @returns 지원 여부
15
- */
16
- export async function isValidLocale(locale) {
17
- const locales = await import('./locale.actions.js').then(m => m.getLocales());
18
- return locales.includes(locale);
19
- }
20
- //# sourceMappingURL=locale.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../src/helpers/locale.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB;;;;;GAKG;AAEH,OAAO,EACH,SAAS,EACT,SAAS,EACT,UAAU,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc;IAE9C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9E,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC"}
@@ -1,41 +0,0 @@
1
- /**
2
- * CMS Sync Utilities
3
- *
4
- * JSON 파일 기반 라벨 동기화
5
- */
6
- import type { SectionDefinition, SyncOptions, SyncResult } from '../types.js';
7
- /**
8
- * 여러 섹션 동기화
9
- */
10
- export declare function syncAll(sections: SectionDefinition[], options?: SyncOptions): Promise<SyncResult[]>;
11
- /**
12
- * JSON 파일에서 라벨 로드
13
- */
14
- export declare function loadLabelsFromJson(labelsDir: string): SectionDefinition[];
15
- /**
16
- * 섹션 라벨 동기화
17
- */
18
- export declare function syncSection(definition: SectionDefinition, options?: SyncOptions): Promise<SyncResult>;
19
- /**
20
- * Initialize label sync for server startup
21
- *
22
- * Call this in your server.config.ts beforeRoutes hook
23
- *
24
- * @param options - Sync options
25
- * @param options.labelsDir - Path to labels directory (default: 'src/cms/labels')
26
- *
27
- * @example
28
- * ```typescript
29
- * import { initLabelSync } from '@spfn/cms';
30
- *
31
- * export default {
32
- * beforeRoutes: async (app) => {
33
- * await initLabelSync({ verbose: true });
34
- * },
35
- * } satisfies ServerConfig;
36
- * ```
37
- */
38
- export declare function initLabelSync(options?: SyncOptions & {
39
- labelsDir?: string;
40
- }): Promise<void>;
41
- //# sourceMappingURL=sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/helpers/sync.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAgB,iBAAiB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE5F;;GAEG;AACH,wBAAsB,OAAO,CACzB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,GAAE,WAAgB,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC,CAWvB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAqCzE;AAqCD;;GAEG;AACH,wBAAsB,WAAW,CAC7B,UAAU,EAAE,iBAAiB,EAC7B,OAAO,GAAE,WAAgB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAoKrB;AAyDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,WAAW,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgErG"}