@spfn/cms 0.1.0-alpha.0

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 (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +490 -0
  3. package/dist/actions.d.ts +9 -0
  4. package/dist/actions.d.ts.map +1 -0
  5. package/dist/actions.js +11 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/client.d.ts +138 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +62 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/cms.config.d.ts +77 -0
  12. package/dist/cms.config.d.ts.map +1 -0
  13. package/dist/cms.config.js +111 -0
  14. package/dist/cms.config.js.map +1 -0
  15. package/dist/entities/cms-audit-logs.d.ts +213 -0
  16. package/dist/entities/cms-audit-logs.d.ts.map +1 -0
  17. package/dist/entities/cms-audit-logs.js +103 -0
  18. package/dist/entities/cms-audit-logs.js.map +1 -0
  19. package/dist/entities/cms-draft-cache.d.ts +188 -0
  20. package/dist/entities/cms-draft-cache.d.ts.map +1 -0
  21. package/dist/entities/cms-draft-cache.js +112 -0
  22. package/dist/entities/cms-draft-cache.js.map +1 -0
  23. package/dist/entities/cms-label-values.d.ts +192 -0
  24. package/dist/entities/cms-label-values.d.ts.map +1 -0
  25. package/dist/entities/cms-label-values.js +105 -0
  26. package/dist/entities/cms-label-values.js.map +1 -0
  27. package/dist/entities/cms-label-versions.d.ts +207 -0
  28. package/dist/entities/cms-label-versions.d.ts.map +1 -0
  29. package/dist/entities/cms-label-versions.js +80 -0
  30. package/dist/entities/cms-label-versions.js.map +1 -0
  31. package/dist/entities/cms-labels.d.ts +189 -0
  32. package/dist/entities/cms-labels.d.ts.map +1 -0
  33. package/dist/entities/cms-labels.js +48 -0
  34. package/dist/entities/cms-labels.js.map +1 -0
  35. package/dist/entities/cms-published-cache.d.ts +199 -0
  36. package/dist/entities/cms-published-cache.d.ts.map +1 -0
  37. package/dist/entities/cms-published-cache.js +103 -0
  38. package/dist/entities/cms-published-cache.js.map +1 -0
  39. package/dist/entities/index.d.ts +10 -0
  40. package/dist/entities/index.d.ts.map +1 -0
  41. package/dist/entities/index.js +10 -0
  42. package/dist/entities/index.js.map +1 -0
  43. package/dist/generators/index.d.ts +19 -0
  44. package/dist/generators/index.d.ts.map +1 -0
  45. package/dist/generators/index.js +19 -0
  46. package/dist/generators/index.js.map +1 -0
  47. package/dist/generators/label-sync-generator.d.ts +33 -0
  48. package/dist/generators/label-sync-generator.d.ts.map +1 -0
  49. package/dist/generators/label-sync-generator.js +86 -0
  50. package/dist/generators/label-sync-generator.js.map +1 -0
  51. package/dist/helpers/locale.actions.d.ts +132 -0
  52. package/dist/helpers/locale.actions.d.ts.map +1 -0
  53. package/dist/helpers/locale.actions.js +210 -0
  54. package/dist/helpers/locale.actions.js.map +1 -0
  55. package/dist/helpers/locale.constants.d.ts +10 -0
  56. package/dist/helpers/locale.constants.d.ts.map +1 -0
  57. package/dist/helpers/locale.constants.js +10 -0
  58. package/dist/helpers/locale.constants.js.map +1 -0
  59. package/dist/helpers/locale.d.ts +17 -0
  60. package/dist/helpers/locale.d.ts.map +1 -0
  61. package/dist/helpers/locale.js +20 -0
  62. package/dist/helpers/locale.js.map +1 -0
  63. package/dist/helpers/sync.d.ts +41 -0
  64. package/dist/helpers/sync.d.ts.map +1 -0
  65. package/dist/helpers/sync.js +309 -0
  66. package/dist/helpers/sync.js.map +1 -0
  67. package/dist/index.d.ts +20 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +24 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/init.d.ts +31 -0
  72. package/dist/init.d.ts.map +1 -0
  73. package/dist/init.js +36 -0
  74. package/dist/init.js.map +1 -0
  75. package/dist/labels/helpers.d.ts +31 -0
  76. package/dist/labels/helpers.d.ts.map +1 -0
  77. package/dist/labels/helpers.js +60 -0
  78. package/dist/labels/helpers.js.map +1 -0
  79. package/dist/labels/index.d.ts +7 -0
  80. package/dist/labels/index.d.ts.map +1 -0
  81. package/dist/labels/index.js +7 -0
  82. package/dist/labels/index.js.map +1 -0
  83. package/dist/repositories/cms-draft-cache.repository.d.ts +62 -0
  84. package/dist/repositories/cms-draft-cache.repository.d.ts.map +1 -0
  85. package/dist/repositories/cms-draft-cache.repository.js +56 -0
  86. package/dist/repositories/cms-draft-cache.repository.js.map +1 -0
  87. package/dist/repositories/cms-label-values.repository.d.ts +32 -0
  88. package/dist/repositories/cms-label-values.repository.d.ts.map +1 -0
  89. package/dist/repositories/cms-label-values.repository.js +72 -0
  90. package/dist/repositories/cms-label-values.repository.js.map +1 -0
  91. package/dist/repositories/cms-labels.repository.d.ts +53 -0
  92. package/dist/repositories/cms-labels.repository.d.ts.map +1 -0
  93. package/dist/repositories/cms-labels.repository.js +77 -0
  94. package/dist/repositories/cms-labels.repository.js.map +1 -0
  95. package/dist/repositories/cms-published-cache.repository.d.ts +53 -0
  96. package/dist/repositories/cms-published-cache.repository.d.ts.map +1 -0
  97. package/dist/repositories/cms-published-cache.repository.js +54 -0
  98. package/dist/repositories/cms-published-cache.repository.js.map +1 -0
  99. package/dist/repositories/index.d.ts +8 -0
  100. package/dist/repositories/index.d.ts.map +1 -0
  101. package/dist/repositories/index.js +9 -0
  102. package/dist/repositories/index.js.map +1 -0
  103. package/dist/routes/labels/[id]/contract.d.ts +68 -0
  104. package/dist/routes/labels/[id]/contract.d.ts.map +1 -0
  105. package/dist/routes/labels/[id]/contract.js +84 -0
  106. package/dist/routes/labels/[id]/contract.js.map +1 -0
  107. package/dist/routes/labels/[id]/index.d.ts +10 -0
  108. package/dist/routes/labels/[id]/index.d.ts.map +1 -0
  109. package/dist/routes/labels/[id]/index.js +96 -0
  110. package/dist/routes/labels/[id]/index.js.map +1 -0
  111. package/dist/routes/labels/by-key/[key]/contract.d.ts +24 -0
  112. package/dist/routes/labels/by-key/[key]/contract.d.ts.map +1 -0
  113. package/dist/routes/labels/by-key/[key]/contract.js +28 -0
  114. package/dist/routes/labels/by-key/[key]/contract.js.map +1 -0
  115. package/dist/routes/labels/by-key/[key]/index.d.ts +8 -0
  116. package/dist/routes/labels/by-key/[key]/index.d.ts.map +1 -0
  117. package/dist/routes/labels/by-key/[key]/index.js +32 -0
  118. package/dist/routes/labels/by-key/[key]/index.js.map +1 -0
  119. package/dist/routes/labels/contract.d.ts +59 -0
  120. package/dist/routes/labels/contract.d.ts.map +1 -0
  121. package/dist/routes/labels/contract.js +75 -0
  122. package/dist/routes/labels/contract.js.map +1 -0
  123. package/dist/routes/labels/index.d.ts +10 -0
  124. package/dist/routes/labels/index.d.ts.map +1 -0
  125. package/dist/routes/labels/index.js +73 -0
  126. package/dist/routes/labels/index.js.map +1 -0
  127. package/dist/routes/published-cache/contract.d.ts +25 -0
  128. package/dist/routes/published-cache/contract.d.ts.map +1 -0
  129. package/dist/routes/published-cache/contract.js +35 -0
  130. package/dist/routes/published-cache/contract.js.map +1 -0
  131. package/dist/routes/published-cache/index.d.ts +8 -0
  132. package/dist/routes/published-cache/index.d.ts.map +1 -0
  133. package/dist/routes/published-cache/index.js +33 -0
  134. package/dist/routes/published-cache/index.js.map +1 -0
  135. package/dist/routes/sync/contract.d.ts +33 -0
  136. package/dist/routes/sync/contract.d.ts.map +1 -0
  137. package/dist/routes/sync/contract.js +34 -0
  138. package/dist/routes/sync/contract.js.map +1 -0
  139. package/dist/routes/sync/index.d.ts +13 -0
  140. package/dist/routes/sync/index.d.ts.map +1 -0
  141. package/dist/routes/sync/index.js +241 -0
  142. package/dist/routes/sync/index.js.map +1 -0
  143. package/dist/routes/values/[labelId]/[version]/contract.d.ts +29 -0
  144. package/dist/routes/values/[labelId]/[version]/contract.d.ts.map +1 -0
  145. package/dist/routes/values/[labelId]/[version]/contract.js +33 -0
  146. package/dist/routes/values/[labelId]/[version]/contract.js.map +1 -0
  147. package/dist/routes/values/[labelId]/[version]/index.d.ts +8 -0
  148. package/dist/routes/values/[labelId]/[version]/index.d.ts.map +1 -0
  149. package/dist/routes/values/[labelId]/[version]/index.js +45 -0
  150. package/dist/routes/values/[labelId]/[version]/index.js.map +1 -0
  151. package/dist/routes/values/[labelId]/contract.d.ts +38 -0
  152. package/dist/routes/values/[labelId]/contract.d.ts.map +1 -0
  153. package/dist/routes/values/[labelId]/contract.js +59 -0
  154. package/dist/routes/values/[labelId]/contract.js.map +1 -0
  155. package/dist/routes/values/[labelId]/index.d.ts +8 -0
  156. package/dist/routes/values/[labelId]/index.d.ts.map +1 -0
  157. package/dist/routes/values/[labelId]/index.js +42 -0
  158. package/dist/routes/values/[labelId]/index.js.map +1 -0
  159. package/dist/server.d.ts +99 -0
  160. package/dist/server.d.ts.map +1 -0
  161. package/dist/server.js +256 -0
  162. package/dist/server.js.map +1 -0
  163. package/dist/store.d.ts +87 -0
  164. package/dist/store.d.ts.map +1 -0
  165. package/dist/store.js +205 -0
  166. package/dist/store.js.map +1 -0
  167. package/dist/sync.d.ts +11 -0
  168. package/dist/sync.d.ts.map +1 -0
  169. package/dist/sync.js +179 -0
  170. package/dist/sync.js.map +1 -0
  171. package/dist/types.d.ts +74 -0
  172. package/dist/types.d.ts.map +1 -0
  173. package/dist/types.js +7 -0
  174. package/dist/types.js.map +1 -0
  175. package/package.json +95 -0
package/dist/client.js ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @spfn/cms/client
3
+ *
4
+ * Client Components Only
5
+ * 클라이언트 컴포넌트 전용 (브라우저에서 실행)
6
+ */
7
+ import { client } from '@spfn/core/client';
8
+ // Labels
9
+ import { getLabelsContract, createLabelContract } from './routes/labels/contract';
10
+ import { getLabelContract, updateLabelContract, deleteLabelContract } from './routes/labels/[id]/contract';
11
+ // Published Cache
12
+ import { getPublishedCacheContract } from './routes/published-cache/contract';
13
+ /**
14
+ * CMS API Client
15
+ */
16
+ export const cmsApi = {
17
+ /**
18
+ * Labels API
19
+ */
20
+ labels: {
21
+ /**
22
+ * GET /cms/labels
23
+ * 라벨 목록 조회 (섹션 필터, 페이지네이션)
24
+ */
25
+ list: (options) => client.call('/cms/labels', getLabelsContract, options),
26
+ /**
27
+ * GET /cms/labels/:id
28
+ * 특정 라벨 조회
29
+ */
30
+ getById: (options) => client.call('/cms/labels/:id', getLabelContract, options),
31
+ /**
32
+ * POST /cms/labels
33
+ * 새 라벨 생성
34
+ */
35
+ create: (options) => client.call('/cms/labels', createLabelContract, options),
36
+ /**
37
+ * PATCH /cms/labels/:id
38
+ * 라벨 업데이트
39
+ */
40
+ update: (options) => client.call('/cms/labels/:id', updateLabelContract, options),
41
+ /**
42
+ * DELETE /cms/labels/:id
43
+ * 라벨 삭제
44
+ */
45
+ delete: (options) => client.call('/cms/labels/:id', deleteLabelContract, options),
46
+ },
47
+ /**
48
+ * Published Cache API
49
+ */
50
+ publishedCache: {
51
+ /**
52
+ * GET /cms/published-cache
53
+ * 발행된 콘텐츠 캐시 조회
54
+ */
55
+ get: (options) => client.call('/cms/published-cache', getPublishedCacheContract, options),
56
+ },
57
+ };
58
+ // Client-side Store & Hooks
59
+ export { useCmsStore, useSection, useSections } from './store';
60
+ // Client-side Initializer
61
+ export { InitCms } from './init';
62
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,SAAS;AACT,OAAO,EACH,iBAAiB,EACjB,mBAAmB,EACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACH,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACtB,MAAM,+BAA+B,CAAC;AAEvC,kBAAkB;AAClB,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAE9E;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IAClB;;OAEG;IACH,MAAM,EAAE;QACJ;;;WAGG;QACH,IAAI,EAAE,CAAC,OAAsE,EAAE,EAAE,CAC7E,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,EAAE,OAAO,CAAC;QAE1D;;;WAGG;QACH,OAAO,EAAE,CAAC,OAAqE,EAAE,EAAE,CAC/E,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,gBAAgB,EAAE,OAAO,CAAC;QAE7D;;;WAGG;QACH,MAAM,EAAE,CAAC,OAAoE,EAAE,EAAE,CAC7E,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,mBAAmB,EAAE,OAAO,CAAC;QAE5D;;;WAGG;QACH,MAAM,EAAE,CAAC,OAGR,EAAE,EAAE,CACD,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,OAAO,CAAC;QAEhE;;;WAGG;QACH,MAAM,EAAE,CAAC,OAAwE,EAAE,EAAE,CACjF,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,OAAO,CAAC;KACnE;IAED;;OAEG;IACH,cAAc,EAAE;QACZ;;;WAGG;QACH,GAAG,EAAE,CAAC,OAA4E,EAAE,EAAE,CAClF,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,yBAAyB,EAAE,OAAO,CAAC;KAC9E;CACK,CAAC;AAOX,4BAA4B;AAC5B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,0BAA0B;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * CMS Configuration Module
3
+ *
4
+ * 환경변수 기반 CMS 설정 관리
5
+ * - SPFN_CMS_DEFAULT_LOCALE: 기본 언어 (기본값: 'ko')
6
+ * - SPFN_CMS_SUPPORTED_LOCALES: 지원 언어 목록, 쉼표로 구분 (기본값: 'ko,en')
7
+ * - SPFN_CMS_DETECT_BROWSER_LANGUAGE: 브라우저 언어 자동 감지 (기본값: 'false')
8
+ */
9
+ /**
10
+ * CMS 설정 타입
11
+ */
12
+ export interface CmsConfig {
13
+ /**
14
+ * 기본 언어 코드
15
+ * @example 'ko', 'en', 'ja'
16
+ */
17
+ defaultLocale: string;
18
+ /**
19
+ * 지원하는 언어 목록
20
+ * @example ['ko', 'en', 'ja']
21
+ */
22
+ supportedLocales: string[];
23
+ /**
24
+ * 브라우저 언어 자동 감지 여부
25
+ * @default false
26
+ */
27
+ detectBrowserLanguage: boolean;
28
+ }
29
+ /**
30
+ * CMS 설정 조회
31
+ *
32
+ * @returns 현재 CMS 설정
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * import { getCmsConfig } from '@spfn/cms';
37
+ *
38
+ * const config = getCmsConfig();
39
+ * console.log(config.defaultLocale); // 'ko'
40
+ * console.log(config.supportedLocales); // ['ko', 'en']
41
+ * ```
42
+ */
43
+ export declare function getCmsConfig(): Readonly<CmsConfig>;
44
+ /**
45
+ * CMS 설정 변경 (런타임 오버라이드)
46
+ *
47
+ * 환경변수 설정을 런타임에 오버라이드합니다.
48
+ * 주로 테스트나 특수한 경우에 사용됩니다.
49
+ *
50
+ * @param config - 변경할 설정 (부분 업데이트 가능)
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * import { configureCms } from '@spfn/cms';
55
+ *
56
+ * // 앱 초기화 시 (선택적)
57
+ * configureCms({
58
+ * defaultLocale: 'en',
59
+ * supportedLocales: ['en', 'ko', 'ja'],
60
+ * detectBrowserLanguage: true,
61
+ * });
62
+ * ```
63
+ */
64
+ export declare function configureCms(config: Partial<CmsConfig>): void;
65
+ /**
66
+ * 설정 초기화 (환경변수에서 재로드)
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * import { resetCmsConfig } from '@spfn/cms';
71
+ *
72
+ * // 환경변수 설정으로 되돌리기
73
+ * resetCmsConfig();
74
+ * ```
75
+ */
76
+ export declare function resetCmsConfig(): void;
77
+ //# sourceMappingURL=cms.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms.config.d.ts","sourceRoot":"","sources":["../src/cms.config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IAEtB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAE3B;;;OAGG;IACH,qBAAqB,EAAE,OAAO,CAAC;CAClC;AAoDD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CAAC,SAAS,CAAC,CAGlD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAiB7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * CMS Configuration Module
3
+ *
4
+ * 환경변수 기반 CMS 설정 관리
5
+ * - SPFN_CMS_DEFAULT_LOCALE: 기본 언어 (기본값: 'ko')
6
+ * - SPFN_CMS_SUPPORTED_LOCALES: 지원 언어 목록, 쉼표로 구분 (기본값: 'ko,en')
7
+ * - SPFN_CMS_DETECT_BROWSER_LANGUAGE: 브라우저 언어 자동 감지 (기본값: 'false')
8
+ */
9
+ /**
10
+ * 환경변수 읽기 헬퍼
11
+ */
12
+ function getEnvVar(key, defaultValue) {
13
+ return process.env[key] || defaultValue;
14
+ }
15
+ /**
16
+ * 환경변수에서 boolean 읽기
17
+ */
18
+ function getEnvBoolean(key, defaultValue) {
19
+ const value = process.env[key];
20
+ if (value === undefined)
21
+ return defaultValue;
22
+ return value === 'true' || value === '1';
23
+ }
24
+ /**
25
+ * 환경변수에서 설정 로드
26
+ */
27
+ function loadConfigFromEnv() {
28
+ const defaultLocale = getEnvVar('SPFN_CMS_DEFAULT_LOCALE', 'en');
29
+ const supportedLocalesStr = getEnvVar('SPFN_CMS_SUPPORTED_LOCALES', 'en,ko');
30
+ const detectBrowserLanguage = getEnvBoolean('SPFN_CMS_DETECT_BROWSER_LANGUAGE', true);
31
+ const supportedLocales = supportedLocalesStr
32
+ .split(',')
33
+ .map(locale => locale.trim())
34
+ .filter(locale => locale.length > 0);
35
+ // 기본 언어가 지원 목록에 없으면 추가
36
+ if (!supportedLocales.includes(defaultLocale)) {
37
+ supportedLocales.unshift(defaultLocale);
38
+ }
39
+ return {
40
+ defaultLocale,
41
+ supportedLocales,
42
+ detectBrowserLanguage,
43
+ };
44
+ }
45
+ /**
46
+ * 현재 설정 (환경변수에서 초기화)
47
+ */
48
+ let currentConfig = loadConfigFromEnv();
49
+ /**
50
+ * CMS 설정 조회
51
+ *
52
+ * @returns 현재 CMS 설정
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * import { getCmsConfig } from '@spfn/cms';
57
+ *
58
+ * const config = getCmsConfig();
59
+ * console.log(config.defaultLocale); // 'ko'
60
+ * console.log(config.supportedLocales); // ['ko', 'en']
61
+ * ```
62
+ */
63
+ export function getCmsConfig() {
64
+ return currentConfig;
65
+ }
66
+ /**
67
+ * CMS 설정 변경 (런타임 오버라이드)
68
+ *
69
+ * 환경변수 설정을 런타임에 오버라이드합니다.
70
+ * 주로 테스트나 특수한 경우에 사용됩니다.
71
+ *
72
+ * @param config - 변경할 설정 (부분 업데이트 가능)
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * import { configureCms } from '@spfn/cms';
77
+ *
78
+ * // 앱 초기화 시 (선택적)
79
+ * configureCms({
80
+ * defaultLocale: 'en',
81
+ * supportedLocales: ['en', 'ko', 'ja'],
82
+ * detectBrowserLanguage: true,
83
+ * });
84
+ * ```
85
+ */
86
+ export function configureCms(config) {
87
+ currentConfig = {
88
+ ...currentConfig,
89
+ ...config,
90
+ };
91
+ // 기본 언어가 지원 목록에 있는지 확인
92
+ if (config.defaultLocale && !currentConfig.supportedLocales.includes(config.defaultLocale)) {
93
+ console.warn(`[CMS Config] Default locale '${config.defaultLocale}' not in supported locales, adding automatically.`, `Supported locales: [${currentConfig.supportedLocales.join(', ')}]`);
94
+ currentConfig.supportedLocales.unshift(config.defaultLocale);
95
+ }
96
+ }
97
+ /**
98
+ * 설정 초기화 (환경변수에서 재로드)
99
+ *
100
+ * @example
101
+ * ```tsx
102
+ * import { resetCmsConfig } from '@spfn/cms';
103
+ *
104
+ * // 환경변수 설정으로 되돌리기
105
+ * resetCmsConfig();
106
+ * ```
107
+ */
108
+ export function resetCmsConfig() {
109
+ currentConfig = loadConfigFromEnv();
110
+ }
111
+ //# sourceMappingURL=cms.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms.config.js","sourceRoot":"","sources":["../src/cms.config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0BH;;GAEG;AACH,SAAS,SAAS,CAAC,GAAW,EAAE,YAAoB;IAEhD,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,GAAW,EAAE,YAAqB;IAErD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC;IAC7C,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB;IAEtB,MAAM,aAAa,GAAG,SAAS,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,mBAAmB,GAAG,SAAS,CAAC,4BAA4B,EAAE,OAAO,CAAC,CAAC;IAC7E,MAAM,qBAAqB,GAAG,aAAa,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;IAEtF,MAAM,gBAAgB,GAAG,mBAAmB;SACvC,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEzC,uBAAuB;IACvB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,aAAa,CAAC,EAC7C,CAAC;QACG,gBAAgB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO;QACH,aAAa;QACb,gBAAgB;QAChB,qBAAqB;KACxB,CAAC;AACN,CAAC;AAED;;GAEG;AACH,IAAI,aAAa,GAAc,iBAAiB,EAAE,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY;IAExB,OAAO,aAAa,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY,CAAC,MAA0B;IAEnD,aAAa,GAAG;QACZ,GAAG,aAAa;QAChB,GAAG,MAAM;KACZ,CAAC;IAEF,uBAAuB;IACvB,IAAI,MAAM,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,EAC1F,CAAC;QACG,OAAO,CAAC,IAAI,CACR,gCAAgC,MAAM,CAAC,aAAa,mDAAmD,EACvG,uBAAuB,aAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACtE,CAAC;QAEF,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACjE,CAAC;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc;IAE1B,aAAa,GAAG,iBAAiB,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,213 @@
1
+ /**
2
+ * CMS Audit Logs Entity
3
+ *
4
+ * CMS의 모든 변경사항을 추적합니다.
5
+ * - 누가 (userId, userName)
6
+ * - 언제 (createdAt)
7
+ * - 무엇을 (action, changes)
8
+ * - 왜 (metadata)
9
+ */
10
+ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColumns<{
11
+ name: "audit_logs";
12
+ schema: string;
13
+ columns: {
14
+ id: import("drizzle-orm/pg-core").PgColumn<{
15
+ name: "id";
16
+ tableName: "audit_logs";
17
+ dataType: "number";
18
+ columnType: "PgSerial";
19
+ data: number;
20
+ driverParam: number;
21
+ notNull: true;
22
+ hasDefault: true;
23
+ isPrimaryKey: true;
24
+ isAutoincrement: false;
25
+ hasRuntimeDefault: false;
26
+ enumValues: undefined;
27
+ baseColumn: never;
28
+ identity: undefined;
29
+ generated: undefined;
30
+ }, {}, {}>;
31
+ labelId: import("drizzle-orm/pg-core").PgColumn<{
32
+ name: "label_id";
33
+ tableName: "audit_logs";
34
+ dataType: "number";
35
+ columnType: "PgInteger";
36
+ data: number;
37
+ driverParam: string | number;
38
+ notNull: false;
39
+ hasDefault: false;
40
+ isPrimaryKey: false;
41
+ isAutoincrement: false;
42
+ hasRuntimeDefault: false;
43
+ enumValues: undefined;
44
+ baseColumn: never;
45
+ identity: undefined;
46
+ generated: undefined;
47
+ }, {}, {}>;
48
+ action: import("drizzle-orm/pg-core").PgColumn<{
49
+ name: "action";
50
+ tableName: "audit_logs";
51
+ dataType: "string";
52
+ columnType: "PgText";
53
+ data: string;
54
+ driverParam: string;
55
+ notNull: true;
56
+ hasDefault: false;
57
+ isPrimaryKey: false;
58
+ isAutoincrement: false;
59
+ hasRuntimeDefault: false;
60
+ enumValues: [string, ...string[]];
61
+ baseColumn: never;
62
+ identity: undefined;
63
+ generated: undefined;
64
+ }, {}, {}>;
65
+ userId: import("drizzle-orm/pg-core").PgColumn<{
66
+ name: "user_id";
67
+ tableName: "audit_logs";
68
+ dataType: "string";
69
+ columnType: "PgText";
70
+ data: string;
71
+ driverParam: string;
72
+ notNull: true;
73
+ hasDefault: false;
74
+ isPrimaryKey: false;
75
+ isAutoincrement: false;
76
+ hasRuntimeDefault: false;
77
+ enumValues: [string, ...string[]];
78
+ baseColumn: never;
79
+ identity: undefined;
80
+ generated: undefined;
81
+ }, {}, {}>;
82
+ userName: import("drizzle-orm/pg-core").PgColumn<{
83
+ name: "user_name";
84
+ tableName: "audit_logs";
85
+ dataType: "string";
86
+ columnType: "PgText";
87
+ data: string;
88
+ driverParam: string;
89
+ notNull: false;
90
+ hasDefault: false;
91
+ isPrimaryKey: false;
92
+ isAutoincrement: false;
93
+ hasRuntimeDefault: false;
94
+ enumValues: [string, ...string[]];
95
+ baseColumn: never;
96
+ identity: undefined;
97
+ generated: undefined;
98
+ }, {}, {}>;
99
+ changes: import("drizzle-orm/pg-core").PgColumn<{
100
+ name: "changes";
101
+ tableName: "audit_logs";
102
+ dataType: "json";
103
+ columnType: "PgJsonb";
104
+ data: unknown;
105
+ driverParam: unknown;
106
+ notNull: false;
107
+ hasDefault: false;
108
+ isPrimaryKey: false;
109
+ isAutoincrement: false;
110
+ hasRuntimeDefault: false;
111
+ enumValues: undefined;
112
+ baseColumn: never;
113
+ identity: undefined;
114
+ generated: undefined;
115
+ }, {}, {}>;
116
+ metadata: import("drizzle-orm/pg-core").PgColumn<{
117
+ name: "metadata";
118
+ tableName: "audit_logs";
119
+ dataType: "json";
120
+ columnType: "PgJsonb";
121
+ data: unknown;
122
+ driverParam: unknown;
123
+ notNull: false;
124
+ hasDefault: false;
125
+ isPrimaryKey: false;
126
+ isAutoincrement: false;
127
+ hasRuntimeDefault: false;
128
+ enumValues: undefined;
129
+ baseColumn: never;
130
+ identity: undefined;
131
+ generated: undefined;
132
+ }, {}, {}>;
133
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
134
+ name: "created_at";
135
+ tableName: "audit_logs";
136
+ dataType: "date";
137
+ columnType: "PgTimestamp";
138
+ data: Date;
139
+ driverParam: string;
140
+ notNull: true;
141
+ hasDefault: true;
142
+ isPrimaryKey: false;
143
+ isAutoincrement: false;
144
+ hasRuntimeDefault: false;
145
+ enumValues: undefined;
146
+ baseColumn: never;
147
+ identity: undefined;
148
+ generated: undefined;
149
+ }, {}, {}>;
150
+ };
151
+ dialect: "pg";
152
+ }>;
153
+ export type CmsAuditLog = typeof cmsAuditLogs.$inferSelect;
154
+ export type NewCmsAuditLog = typeof cmsAuditLogs.$inferInsert;
155
+ /**
156
+ * 사용 예시:
157
+ *
158
+ * // 라벨 생성 로그
159
+ * await db.insert(cmsAuditLogs).values({
160
+ * labelId: 1,
161
+ * action: 'create',
162
+ * userId: 'user123',
163
+ * userName: '김철수',
164
+ * changes: {
165
+ * before: null,
166
+ * after: {
167
+ * key: 'home.hero.title',
168
+ * section: 'home',
169
+ * type: 'text'
170
+ * }
171
+ * },
172
+ * metadata: {
173
+ * ip: '192.168.1.1',
174
+ * userAgent: 'Mozilla/5.0...'
175
+ * }
176
+ * });
177
+ *
178
+ * // 발행 로그
179
+ * await db.insert(cmsAuditLogs).values({
180
+ * labelId: 1,
181
+ * action: 'publish',
182
+ * userId: 'admin123',
183
+ * userName: '관리자',
184
+ * changes: {
185
+ * before: { status: 'draft', publishedVersion: null },
186
+ * after: { status: 'published', publishedVersion: 2 }
187
+ * },
188
+ * metadata: {
189
+ * version: 2,
190
+ * notes: '신규 브랜딩 적용'
191
+ * }
192
+ * });
193
+ *
194
+ * // 라벨별 이력 조회
195
+ * const logs = await db.select()
196
+ * .from(cmsAuditLogs)
197
+ * .where(eq(cmsAuditLogs.labelId, 1))
198
+ * .orderBy(desc(cmsAuditLogs.createdAt))
199
+ * .limit(20);
200
+ *
201
+ * // 사용자별 활동 조회
202
+ * const userActivity = await db.select()
203
+ * .from(cmsAuditLogs)
204
+ * .where(eq(cmsAuditLogs.userId, 'user123'))
205
+ * .orderBy(desc(cmsAuditLogs.createdAt));
206
+ *
207
+ * // 최근 24시간 변경 이력
208
+ * const recent = await db.select()
209
+ * .from(cmsAuditLogs)
210
+ * .where(gte(cmsAuditLogs.createdAt, new Date(Date.now() - 24 * 60 * 60 * 1000)))
211
+ * .orderBy(desc(cmsAuditLogs.createdAt));
212
+ */
213
+ //# sourceMappingURL=cms-audit-logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-audit-logs.d.ts","sourceRoot":"","sources":["../../src/entities/cms-audit-logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCvB,CAAC;AAGH,MAAM,MAAM,WAAW,GAAG,OAAO,YAAY,CAAC,YAAY,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,OAAO,YAAY,CAAC,YAAY,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * CMS Audit Logs Entity
3
+ *
4
+ * CMS의 모든 변경사항을 추적합니다.
5
+ * - 누가 (userId, userName)
6
+ * - 언제 (createdAt)
7
+ * - 무엇을 (action, changes)
8
+ * - 왜 (metadata)
9
+ */
10
+ import { serial, integer, text, jsonb, timestamp, index } from 'drizzle-orm/pg-core';
11
+ import { createFunctionSchema } from '@spfn/core/db';
12
+ import { cmsLabels } from './cms-labels';
13
+ // Create isolated schema for @spfn/cms
14
+ const schema = createFunctionSchema('@spfn/cms');
15
+ export const cmsAuditLogs = schema.table('audit_logs', {
16
+ // Primary Key
17
+ id: serial('id').primaryKey(),
18
+ // Foreign Key: cms_labels (nullable - 라벨 삭제 시 로그는 유지)
19
+ labelId: integer('label_id')
20
+ .references(() => cmsLabels.id, { onDelete: 'set null' }),
21
+ // 작업 유형
22
+ action: text('action').notNull(),
23
+ // "create" | "update" | "publish" | "unpublish" | "archive" | "delete" | "rollback" | "duplicate"
24
+ // 사용자 정보
25
+ userId: text('user_id').notNull(),
26
+ userName: text('user_name'),
27
+ // 변경 내용 (before/after)
28
+ changes: jsonb('changes'),
29
+ // { before: {...}, after: {...} }
30
+ // 추가 메타데이터
31
+ metadata: jsonb('metadata'),
32
+ // { version: number, ip: string, userAgent: string, ... }
33
+ // 작업 시각
34
+ createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
35
+ }, (table) => [
36
+ // 인덱스: labelId로 이력 조회 최적화
37
+ index('cms_audit_logs_label_id_idx').on(table.labelId),
38
+ // 인덱스: userId로 사용자 활동 조회 최적화
39
+ index('cms_audit_logs_user_id_idx').on(table.userId),
40
+ // 인덱스: action 필터링 최적화
41
+ index('cms_audit_logs_action_idx').on(table.action),
42
+ // 인덱스: 시간순 조회 최적화
43
+ index('cms_audit_logs_created_at_idx').on(table.createdAt),
44
+ ]);
45
+ /**
46
+ * 사용 예시:
47
+ *
48
+ * // 라벨 생성 로그
49
+ * await db.insert(cmsAuditLogs).values({
50
+ * labelId: 1,
51
+ * action: 'create',
52
+ * userId: 'user123',
53
+ * userName: '김철수',
54
+ * changes: {
55
+ * before: null,
56
+ * after: {
57
+ * key: 'home.hero.title',
58
+ * section: 'home',
59
+ * type: 'text'
60
+ * }
61
+ * },
62
+ * metadata: {
63
+ * ip: '192.168.1.1',
64
+ * userAgent: 'Mozilla/5.0...'
65
+ * }
66
+ * });
67
+ *
68
+ * // 발행 로그
69
+ * await db.insert(cmsAuditLogs).values({
70
+ * labelId: 1,
71
+ * action: 'publish',
72
+ * userId: 'admin123',
73
+ * userName: '관리자',
74
+ * changes: {
75
+ * before: { status: 'draft', publishedVersion: null },
76
+ * after: { status: 'published', publishedVersion: 2 }
77
+ * },
78
+ * metadata: {
79
+ * version: 2,
80
+ * notes: '신규 브랜딩 적용'
81
+ * }
82
+ * });
83
+ *
84
+ * // 라벨별 이력 조회
85
+ * const logs = await db.select()
86
+ * .from(cmsAuditLogs)
87
+ * .where(eq(cmsAuditLogs.labelId, 1))
88
+ * .orderBy(desc(cmsAuditLogs.createdAt))
89
+ * .limit(20);
90
+ *
91
+ * // 사용자별 활동 조회
92
+ * const userActivity = await db.select()
93
+ * .from(cmsAuditLogs)
94
+ * .where(eq(cmsAuditLogs.userId, 'user123'))
95
+ * .orderBy(desc(cmsAuditLogs.createdAt));
96
+ *
97
+ * // 최근 24시간 변경 이력
98
+ * const recent = await db.select()
99
+ * .from(cmsAuditLogs)
100
+ * .where(gte(cmsAuditLogs.createdAt, new Date(Date.now() - 24 * 60 * 60 * 1000)))
101
+ * .orderBy(desc(cmsAuditLogs.createdAt));
102
+ */
103
+ //# sourceMappingURL=cms-audit-logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-audit-logs.js","sourceRoot":"","sources":["../../src/entities/cms-audit-logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,uCAAuC;AACvC,MAAM,MAAM,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE;IACnD,cAAc;IACd,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAE7B,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC;SAC3B,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAEzD,QAAQ;IACR,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE;IAChC,kGAAkG;IAElG,SAAS;IACT,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;IACjC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC;IAE3B,uBAAuB;IACvB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,kCAAkC;IAElC,WAAW;IACX,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC;IAC3B,0DAA0D;IAE1D,QAAQ;IACR,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE;CACpF,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;IACV,0BAA0B;IAC1B,KAAK,CAAC,6BAA6B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;IAEtD,6BAA6B;IAC7B,KAAK,CAAC,4BAA4B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;IAEpD,sBAAsB;IACtB,KAAK,CAAC,2BAA2B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;IAEnD,kBAAkB;IAClB,KAAK,CAAC,+BAA+B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;CAC7D,CAAC,CAAC;AAMH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG"}