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

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 +44 -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,33 +0,0 @@
1
- import { Type } from '@sinclair/typebox';
2
- /**
3
- * GET /cms/values/:labelId/:version - 특정 버전의 값 조회
4
- */
5
- export const getValuesContract = {
6
- method: 'GET',
7
- path: '/:labelId/:version',
8
- params: Type.Object({
9
- labelId: Type.String({ description: '라벨 ID' }),
10
- version: Type.String({ description: '버전 번호' })
11
- }),
12
- query: Type.Object({
13
- locale: Type.Optional(Type.String({ description: '언어 코드 (ko, en, ja)' })),
14
- breakpoint: Type.Optional(Type.String({ description: '반응형 브레이크포인트' }))
15
- }),
16
- response: Type.Union([
17
- Type.Object({
18
- labelId: Type.Number(),
19
- version: Type.Number(),
20
- values: Type.Array(Type.Object({
21
- id: Type.Number(),
22
- locale: Type.String(),
23
- breakpoint: Type.Union([Type.String(), Type.Null()]),
24
- value: Type.Any(),
25
- createdAt: Type.String()
26
- }))
27
- }),
28
- Type.Object({
29
- error: Type.String()
30
- })
31
- ])
32
- };
33
- //# sourceMappingURL=contract.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../../../src/routes/values/[labelId]/[version]/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC7B,MAAM,EAAE,KAAc;IACtB,IAAI,EAAE,oBAAoB;IAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QAChB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;QAC9C,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;KACjD,CAAC;IACF,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;QACf,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACzE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC;KACzE,CAAC;IACF,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC;QACjB,IAAI,CAAC,MAAM,CAAC;YACR,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE;YACtB,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE;YACtB,MAAM,EAAE,IAAI,CAAC,KAAK,CACd,IAAI,CAAC,MAAM,CAAC;gBACR,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;gBACrB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACpD,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE;gBACjB,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;aAC3B,CAAC,CACL;SACJ,CAAC;QACF,IAAI,CAAC,MAAM,CAAC;YACR,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE;SACvB,CAAC;KACL,CAAC;CAC4B,CAAC"}
@@ -1,8 +0,0 @@
1
- /**
2
- * CMS Label Values Detail Routes
3
- *
4
- * - GET /cms/values/:labelId/:version - 특정 버전의 값 조회
5
- */
6
- declare const app: import("@spfn/core/route").SPFNApp;
7
- export default app;
8
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/routes/values/[labelId]/[version]/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,QAAA,MAAM,GAAG,oCAAc,CAAC;AAiDxB,eAAe,GAAG,CAAC"}
@@ -1,45 +0,0 @@
1
- /**
2
- * CMS Label Values Detail Routes
3
- *
4
- * - GET /cms/values/:labelId/:version - 특정 버전의 값 조회
5
- */
6
- import { createApp } from '@spfn/core/route';
7
- import { cmsLabelsRepository, cmsLabelValuesRepository } from '../../../../repositories/index.js';
8
- import { getValuesContract } from './contract.js';
9
- const app = createApp();
10
- /**
11
- * GET /cms/values/:labelId/:version
12
- * 특정 버전의 값 조회
13
- */
14
- app.bind(getValuesContract, async (c) => {
15
- const { labelId: labelIdStr, version: versionStr } = c.params;
16
- const labelId = parseInt(labelIdStr, 10);
17
- const version = parseInt(versionStr, 10);
18
- if (isNaN(labelId) || isNaN(version)) {
19
- return c.json({ error: 'Invalid label ID or version' }, 400);
20
- }
21
- const { locale, breakpoint } = c.query;
22
- // 라벨 존재 확인
23
- const label = await cmsLabelsRepository.findById(labelId);
24
- if (!label) {
25
- return c.json({ error: 'Label not found' }, 404);
26
- }
27
- // 값 조회
28
- const values = await cmsLabelValuesRepository.findByLabelIdAndVersion(labelId, version, {
29
- locale,
30
- breakpoint: breakpoint === 'null' ? null : breakpoint,
31
- });
32
- return c.json({
33
- labelId,
34
- version,
35
- values: values.map((v) => ({
36
- id: v.id,
37
- locale: v.locale,
38
- breakpoint: v.breakpoint,
39
- value: v.value,
40
- createdAt: v.createdAt.toISOString(),
41
- })),
42
- });
43
- });
44
- export default app;
45
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/routes/values/[labelId]/[version]/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;AAExB;;;GAGG;AACH,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAEpC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9D,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAEzC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,EACpC,CAAC;QACG,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC;IAEvC,WAAW;IACX,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,EACV,CAAC;QACG,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,OAAO;IACP,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC,uBAAuB,CACjE,OAAO,EACP,OAAO,EACP;QACI,MAAM;QACN,UAAU,EAAE,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU;KACxD,CACJ,CAAC;IAEF,OAAO,CAAC,CAAC,IAAI,CAAC;QACV,OAAO;QACP,OAAO;QACP,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE;SACvC,CAAC,CAAC;KACN,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,eAAe,GAAG,CAAC"}
@@ -1,38 +0,0 @@
1
- /**
2
- * POST /cms/values/:labelId - 라벨 값 저장
3
- */
4
- export declare const saveValuesContract: {
5
- readonly method: "POST";
6
- readonly path: "/:labelId";
7
- readonly params: import("@sinclair/typebox").TObject<{
8
- labelId: import("@sinclair/typebox").TString;
9
- }>;
10
- readonly body: import("@sinclair/typebox").TObject<{
11
- version: import("@sinclair/typebox").TNumber;
12
- values: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
13
- locale: import("@sinclair/typebox").TString;
14
- breakpoint: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"sm">, import("@sinclair/typebox").TLiteral<"md">, import("@sinclair/typebox").TLiteral<"lg">, import("@sinclair/typebox").TLiteral<"xl">, import("@sinclair/typebox").TLiteral<"2xl">, import("@sinclair/typebox").TNull]>>;
15
- value: import("@sinclair/typebox").TObject<{
16
- type: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"text">, import("@sinclair/typebox").TLiteral<"image">, import("@sinclair/typebox").TLiteral<"video">, import("@sinclair/typebox").TLiteral<"file">, import("@sinclair/typebox").TLiteral<"object">]>;
17
- content: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
18
- url: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
19
- alt: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
20
- width: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
21
- height: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
22
- thumbnail: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
23
- duration: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
24
- filename: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
25
- size: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
26
- fields: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TAny>;
27
- }>;
28
- }>>;
29
- }>;
30
- readonly response: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
31
- success: import("@sinclair/typebox").TBoolean;
32
- saved: import("@sinclair/typebox").TNumber;
33
- version: import("@sinclair/typebox").TNumber;
34
- }>, import("@sinclair/typebox").TObject<{
35
- error: import("@sinclair/typebox").TString;
36
- }>]>;
37
- };
38
- //# sourceMappingURL=contract.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../../src/routes/values/[labelId]/contract.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCG,CAAC"}
@@ -1,59 +0,0 @@
1
- import { Type } from '@sinclair/typebox';
2
- /**
3
- * Label Value 타입 정의
4
- */
5
- const LabelValueSchema = Type.Object({
6
- type: Type.Union([
7
- Type.Literal('text'),
8
- Type.Literal('image'),
9
- Type.Literal('video'),
10
- Type.Literal('file'),
11
- Type.Literal('object')
12
- ]),
13
- content: Type.Optional(Type.String()), // text type
14
- url: Type.Optional(Type.String()), // image, video, file types
15
- alt: Type.Optional(Type.String()), // image type
16
- width: Type.Optional(Type.Number()), // image type
17
- height: Type.Optional(Type.Number()), // image type
18
- thumbnail: Type.Optional(Type.String()), // video type
19
- duration: Type.Optional(Type.Number()), // video type
20
- filename: Type.Optional(Type.String()), // file type
21
- size: Type.Optional(Type.Number()), // file type
22
- fields: Type.Optional(Type.Any()) // object type - recursive structure
23
- });
24
- /**
25
- * POST /cms/values/:labelId - 라벨 값 저장
26
- */
27
- export const saveValuesContract = {
28
- method: 'POST',
29
- path: '/:labelId',
30
- params: Type.Object({
31
- labelId: Type.String({ description: '라벨 ID' })
32
- }),
33
- body: Type.Object({
34
- version: Type.Number({ description: '버전 번호', minimum: 1 }),
35
- values: Type.Array(Type.Object({
36
- locale: Type.String({ description: '언어 코드 (ko, en, ja)', default: 'ko' }),
37
- breakpoint: Type.Optional(Type.Union([
38
- Type.Literal('sm'),
39
- Type.Literal('md'),
40
- Type.Literal('lg'),
41
- Type.Literal('xl'),
42
- Type.Literal('2xl'),
43
- Type.Null()
44
- ], { description: '반응형 브레이크포인트' })),
45
- value: LabelValueSchema
46
- }))
47
- }),
48
- response: Type.Union([
49
- Type.Object({
50
- success: Type.Boolean(),
51
- saved: Type.Number(),
52
- version: Type.Number()
53
- }),
54
- Type.Object({
55
- error: Type.String()
56
- })
57
- ])
58
- };
59
- //# sourceMappingURL=contract.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../../src/routes/values/[labelId]/contract.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- /**
2
- * CMS Label Values Routes
3
- *
4
- * - POST /cms/values/:labelId - 라벨 값 저장
5
- */
6
- declare const app: import("@spfn/core/route").SPFNApp;
7
- export default app;
8
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/routes/values/[labelId]/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,QAAA,MAAM,GAAG,oCAAc,CAAC;AA2CxB,eAAe,GAAG,CAAC"}
@@ -1,42 +0,0 @@
1
- /**
2
- * CMS Label Values Routes
3
- *
4
- * - POST /cms/values/:labelId - 라벨 값 저장
5
- */
6
- import { createApp } from '@spfn/core/route';
7
- import { Transactional } from '@spfn/core/db';
8
- import { cmsLabelsRepository, cmsLabelValuesRepository } from '../../../repositories/index.js';
9
- import { saveValuesContract } from './contract.js';
10
- const app = createApp();
11
- /**
12
- * POST /cms/values/:labelId
13
- * 라벨 값 저장 (upsert)
14
- */
15
- app.bind(saveValuesContract, [Transactional()], async (c) => {
16
- const { labelId: labelIdStr } = c.params;
17
- const labelId = parseInt(labelIdStr, 10);
18
- if (isNaN(labelId)) {
19
- return c.json({ error: 'Invalid label ID' }, 400);
20
- }
21
- const body = await c.data();
22
- // 라벨 존재 확인
23
- const label = await cmsLabelsRepository.findById(labelId);
24
- if (!label) {
25
- return c.json({ error: 'Label not found' }, 404);
26
- }
27
- // 값 저장
28
- const savedValues = await cmsLabelValuesRepository.upsertMany(body.values.map((v) => ({
29
- labelId,
30
- version: body.version,
31
- locale: v.locale,
32
- breakpoint: v.breakpoint ?? null,
33
- value: v.value,
34
- })));
35
- return c.json({
36
- success: true,
37
- saved: savedValues.length,
38
- version: body.version,
39
- });
40
- });
41
- export default app;
42
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/routes/values/[labelId]/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;AAExB;;;GAGG;AACH,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAExD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAEzC,IAAI,KAAK,CAAC,OAAO,CAAC,EAClB,CAAC;QACG,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAE5B,WAAW;IACX,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,EACV,CAAC;QACG,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,OAAO;IACP,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,UAAU,CACzD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpB,OAAO;QACP,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;QAChC,KAAK,EAAE,CAAC,CAAC,KAAK;KACjB,CAAC,CAAC,CACN,CAAC;IAEF,OAAO,CAAC,CAAC,IAAI,CAAC;QACV,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,WAAW,CAAC,MAAM;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;KACxB,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,eAAe,GAAG,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAiBrB;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,KAAK,yBAAyB,GAAG,CAC7B,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,GAAG,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KACxC,GAAG,CAAC;AAET;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACrB;;;;;;;OAOG;IACH,CAAC,EAAE,yBAAyB,CAAC;IAE7B;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;CACrB,CAAC;AAkBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,UAAU,YACV,MAAM,WACN,MAAM,KAChB,OAAO,CAAC,UAAU,CA2GnB,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,WAAW,aACV,MAAM,EAAE,WACT,MAAM,KAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CA0HnC,CAAC"}
package/dist/store.d.ts DELETED
@@ -1,87 +0,0 @@
1
- /**
2
- * CMS Zustand Store
3
- *
4
- * 클라이언트 컴포넌트에서 CMS 사용을 위한 상태 관리
5
- * - 서버에서 초기화된 데이터를 클라이언트로 전달
6
- * - 클라이언트에서 비동기로 로드 가능
7
- * - 서버 API와 동일한 패턴 ({ t } 사용)
8
- */
9
- import type { SectionData } from './server';
10
- interface CmsState {
11
- /**
12
- * 섹션별 데이터
13
- * { 'home': { section: 'home', content: {...}, version: 1, ... }, ... }
14
- */
15
- sections: Record<string, SectionData>;
16
- /**
17
- * 로딩 상태
18
- */
19
- loading: Record<string, boolean>;
20
- /**
21
- * 섹션 데이터 설정 (서버에서 초기화용)
22
- */
23
- setSection: (section: string, data: SectionData) => void;
24
- /**
25
- * 여러 섹션 한번에 설정
26
- */
27
- setSections: (sections: Record<string, SectionData>) => void;
28
- /**
29
- * 섹션 비동기 로드
30
- */
31
- loadSection: (section: string, locale?: string) => Promise<void>;
32
- /**
33
- * 라벨 업데이트 (Draft Mode용)
34
- */
35
- updateLabel: (section: string, key: string, value: any) => void;
36
- /**
37
- * 초기화
38
- */
39
- reset: () => void;
40
- }
41
- export declare const useCmsStore: import("zustand").UseBoundStore<import("zustand").StoreApi<CmsState>>;
42
- /**
43
- * 섹션 Hook (서버 API와 동일한 패턴)
44
- *
45
- * @param section - 섹션 이름
46
- * @param options - 옵션 (autoLoad: 자동 로드 여부)
47
- * @returns { t, data, loading }
48
- *
49
- * @example
50
- * ```tsx
51
- * 'use client';
52
- * import { useSection } from '@/lib/cms';
53
- *
54
- * export function ClientComponent()
55
- * {
56
- * const { t } = useSection('home');
57
- * return <h1>{t('hero.title')}</h1>;
58
- * }
59
- * ```
60
- */
61
- export declare function useSection(section: string, options?: {
62
- autoLoad?: boolean;
63
- locale?: string;
64
- }): {
65
- t: (key: string, defaultValue?: any, replace?: Record<string, string | number>) => any;
66
- data: SectionData;
67
- loading: boolean;
68
- };
69
- /**
70
- * 여러 섹션 Hook
71
- *
72
- * @param sectionNames - 섹션 이름 배열
73
- * @returns { [section]: { t, data, loading }, ... }
74
- *
75
- * @example
76
- * ```tsx
77
- * const sections = useSections(['home', 'why-futureplay']);
78
- * sections.home.t('hero.title');
79
- * ```
80
- */
81
- export declare function useSections(sectionNames: string[]): Record<string, {
82
- t: (key: string, defaultValue?: any, replace?: Record<string, string | number>) => any;
83
- data: SectionData;
84
- loading: boolean;
85
- }>;
86
- export {};
87
- //# sourceMappingURL=store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAc5C,UAAU,QAAQ;IAEd;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAEtC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjC;;OAEG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC;IAE7D;;OAEG;IACH,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;OAEG;IACH,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAEhE;;OAEG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,uEAkHrB,CAAC;AAEJ;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CACtB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO;aAoB3C,MAAM,iBAAiB,GAAG,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;;;EA+BlF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE;aA7CpC,MAAM,iBAAiB,GAAG,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;;;GAwFlF"}
package/dist/store.js DELETED
@@ -1,205 +0,0 @@
1
- /**
2
- * CMS Zustand Store
3
- *
4
- * 클라이언트 컴포넌트에서 CMS 사용을 위한 상태 관리
5
- * - 서버에서 초기화된 데이터를 클라이언트로 전달
6
- * - 클라이언트에서 비동기로 로드 가능
7
- * - 서버 API와 동일한 패턴 ({ t } 사용)
8
- */
9
- 'use client';
10
- import React from 'react';
11
- import { create } from 'zustand';
12
- import { cmsApi } from './client';
13
- /**
14
- * 변수 치환 헬퍼 (서버와 동일)
15
- */
16
- function replaceVariables(text, replace) {
17
- return text.replace(/\{(\w+)}/g, (match, key) => {
18
- const value = replace[key];
19
- return value !== undefined ? String(value) : match;
20
- });
21
- }
22
- export const useCmsStore = create((set, get) => ({
23
- sections: {},
24
- loading: {},
25
- setSection: (section, data) => {
26
- set((state) => ({
27
- sections: {
28
- ...state.sections,
29
- [section]: data,
30
- },
31
- }));
32
- },
33
- setSections: (sections) => {
34
- set((state) => ({
35
- sections: {
36
- ...state.sections,
37
- ...sections,
38
- },
39
- }));
40
- },
41
- loadSection: async (section, locale = 'ko') => {
42
- const state = get();
43
- // 이미 로드 중이면 스킵
44
- if (state.loading[section]) {
45
- return;
46
- }
47
- // 이미 로드되어 있으면 스킵
48
- if (state.sections[section]) {
49
- return;
50
- }
51
- set((state) => ({
52
- loading: { ...state.loading, [section]: true },
53
- }));
54
- try {
55
- const response = await cmsApi.publishedCache.get({
56
- query: { sections: section, locale },
57
- });
58
- // Check for error response
59
- if ('error' in response) {
60
- console.error(`Failed to load section ${section}:`, response.error);
61
- return;
62
- }
63
- // Response is array, get first element
64
- const data = response[0];
65
- if (!data) {
66
- console.warn(`Section ${section} not found`);
67
- return;
68
- }
69
- const sectionData = {
70
- section: data.section,
71
- locale: data.locale,
72
- content: data.content || {},
73
- version: data.version || 0,
74
- publishedAt: data.publishedAt || null,
75
- };
76
- set((state) => ({
77
- sections: {
78
- ...state.sections,
79
- [section]: sectionData,
80
- },
81
- loading: { ...state.loading, [section]: false },
82
- }));
83
- }
84
- catch (error) {
85
- console.error(`Error loading CMS section ${section}:`, error);
86
- set((state) => ({
87
- loading: { ...state.loading, [section]: false },
88
- }));
89
- }
90
- },
91
- updateLabel: (section, key, value) => {
92
- set((state) => ({
93
- sections: {
94
- ...state.sections,
95
- [section]: {
96
- ...state.sections[section],
97
- content: {
98
- ...state.sections[section]?.content,
99
- [`${section}.${key}`]: value,
100
- },
101
- },
102
- },
103
- }));
104
- },
105
- reset: () => {
106
- set({
107
- sections: {},
108
- loading: {},
109
- });
110
- },
111
- }));
112
- /**
113
- * 섹션 Hook (서버 API와 동일한 패턴)
114
- *
115
- * @param section - 섹션 이름
116
- * @param options - 옵션 (autoLoad: 자동 로드 여부)
117
- * @returns { t, data, loading }
118
- *
119
- * @example
120
- * ```tsx
121
- * 'use client';
122
- * import { useSection } from '@/lib/cms';
123
- *
124
- * export function ClientComponent()
125
- * {
126
- * const { t } = useSection('home');
127
- * return <h1>{t('hero.title')}</h1>;
128
- * }
129
- * ```
130
- */
131
- export function useSection(section, options = {}) {
132
- const { autoLoad = false, locale = 'ko' } = options;
133
- const sectionData = useCmsStore((state) => state.sections[section]);
134
- const loading = useCmsStore((state) => state.loading[section] ?? false);
135
- const loadSection = useCmsStore((state) => state.loadSection);
136
- // 자동 로드 옵션이 켜져있고 데이터가 없으면 로드
137
- React.useEffect(() => {
138
- if (autoLoad && !sectionData && !loading) {
139
- loadSection(section, locale);
140
- }
141
- }, [autoLoad, section, locale, sectionData, loading, loadSection]);
142
- // Translation function (서버와 동일)
143
- const t = React.useCallback((key, defaultValue, replace) => {
144
- if (!sectionData) {
145
- return defaultValue;
146
- }
147
- const fullKey = `${section}.${key}`;
148
- let value = sectionData.content[fullKey];
149
- if (value === undefined) {
150
- value = defaultValue;
151
- }
152
- // 문자열이고 치환 맵이 있으면 변수 치환
153
- if (typeof value === 'string' && replace) {
154
- value = replaceVariables(value, replace);
155
- }
156
- return value;
157
- }, [section, sectionData]);
158
- return {
159
- t,
160
- data: sectionData,
161
- loading,
162
- };
163
- }
164
- /**
165
- * 여러 섹션 Hook
166
- *
167
- * @param sectionNames - 섹션 이름 배열
168
- * @returns { [section]: { t, data, loading }, ... }
169
- *
170
- * @example
171
- * ```tsx
172
- * const sections = useSections(['home', 'why-futureplay']);
173
- * sections.home.t('hero.title');
174
- * ```
175
- */
176
- export function useSections(sectionNames) {
177
- const allSections = useCmsStore((state) => state.sections);
178
- const allLoading = useCmsStore((state) => state.loading);
179
- const result = {};
180
- sectionNames.forEach((section) => {
181
- const sectionData = allSections[section];
182
- const loading = allLoading[section] ?? false;
183
- const t = (key, defaultValue, replace) => {
184
- if (!sectionData) {
185
- return defaultValue;
186
- }
187
- const fullKey = `${section}.${key}`;
188
- let value = sectionData.content[fullKey];
189
- if (value === undefined) {
190
- value = defaultValue;
191
- }
192
- if (typeof value === 'string' && replace) {
193
- value = replaceVariables(value, replace);
194
- }
195
- return value;
196
- };
197
- result[section] = {
198
- t,
199
- data: sectionData,
200
- loading,
201
- };
202
- });
203
- return result;
204
- }
205
- //# sourceMappingURL=store.js.map
package/dist/store.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts DELETED
@@ -1,74 +0,0 @@
1
- /**
2
- * CMS Label Definition Types
3
- *
4
- * 라이브러리 코드 - 향후 @spfn/cms로 분리 예정
5
- */
6
- /**
7
- * 개별 라벨 정의
8
- */
9
- export interface LabelDefinition {
10
- key: string;
11
- defaultValue: string | Record<string, string>;
12
- description?: string;
13
- }
14
- /**
15
- * 중첩된 라벨 구조
16
- * LabelDefinition과 구분하기 위해 key, defaultValue 속성을 명시적으로 제외
17
- */
18
- export type NestedLabels = {
19
- [key: string]: LabelDefinition | NestedLabels;
20
- } & {
21
- key?: never;
22
- defaultValue?: never;
23
- };
24
- /**
25
- * 섹션 정의
26
- */
27
- export interface SectionDefinition {
28
- section: string;
29
- labels: NestedLabels;
30
- }
31
- /**
32
- * Sync 옵션
33
- */
34
- export interface SyncOptions {
35
- /**
36
- * Dry run - 실제로 적용하지 않고 변경사항만 출력
37
- */
38
- dryRun?: boolean;
39
- /**
40
- * 기존 라벨의 defaultValue 업데이트 여부
41
- */
42
- updateExisting?: boolean;
43
- /**
44
- * 사용되지 않는 라벨 삭제 여부
45
- */
46
- removeUnused?: boolean;
47
- /**
48
- * Verbose 출력
49
- */
50
- verbose?: boolean;
51
- }
52
- /**
53
- * Sync 결과
54
- */
55
- export interface SyncResult {
56
- section: string;
57
- created: number;
58
- updated: number;
59
- deleted: number;
60
- unchanged: number;
61
- errors: Array<{
62
- key: string;
63
- error: string;
64
- }>;
65
- }
66
- /**
67
- * 라벨 정의 플랫화된 형태
68
- */
69
- export interface FlatLabel {
70
- key: string;
71
- defaultValue: string | Record<string, string>;
72
- description?: string;
73
- }
74
- //# sourceMappingURL=types.d.ts.map