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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +67 -30
  2. package/dist/actions-CwvmPG0e.d.ts +296 -0
  3. package/dist/actions.d.ts +1 -143
  4. package/dist/actions.js +5 -5
  5. package/dist/actions.js.map +1 -1
  6. package/dist/api.d.ts +376 -0
  7. package/dist/api.js +364 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/client.d.ts +115 -141
  10. package/dist/client.js +860 -63
  11. package/dist/client.js.map +1 -1
  12. package/dist/{types.d.ts → index-Dh5FjWzR.d.ts} +32 -1
  13. package/dist/index.d.ts +21 -43
  14. package/dist/index.js +556 -1061
  15. package/dist/index.js.map +1 -1
  16. package/dist/label-sync-generator-B0EmvtWM.d.ts +32 -0
  17. package/dist/{contracts → lib/contracts}/labels.d.ts +13 -12
  18. package/dist/{contracts → lib/contracts}/labels.js +7 -7
  19. package/dist/lib/contracts/labels.js.map +1 -0
  20. package/dist/{contracts → lib/contracts}/published-cache.d.ts +3 -2
  21. package/dist/{contracts → lib/contracts}/published-cache.js +2 -2
  22. package/dist/lib/contracts/published-cache.js.map +1 -0
  23. package/dist/{contracts → lib/contracts}/values.d.ts +6 -4
  24. package/dist/{contracts → lib/contracts}/values.js +3 -3
  25. package/dist/lib/contracts/values.js.map +1 -0
  26. package/dist/{entities → server/entities}/cms-audit-logs.js +3 -3
  27. package/dist/server/entities/cms-audit-logs.js.map +1 -0
  28. package/dist/{entities → server/entities}/cms-draft-cache.js +1 -1
  29. package/dist/server/entities/cms-draft-cache.js.map +1 -0
  30. package/dist/{entities → server/entities}/cms-label-values.js +3 -3
  31. package/dist/server/entities/cms-label-values.js.map +1 -0
  32. package/dist/{entities → server/entities}/cms-label-versions.js +3 -3
  33. package/dist/server/entities/cms-label-versions.js.map +1 -0
  34. package/dist/{entities → server/entities}/cms-labels.js +1 -1
  35. package/dist/server/entities/cms-labels.js.map +1 -0
  36. package/dist/{entities → server/entities}/cms-published-cache.js +1 -1
  37. package/dist/server/entities/cms-published-cache.js.map +1 -0
  38. package/dist/{entities → server/entities}/index.js +6 -6
  39. package/dist/server/entities/index.js.map +1 -0
  40. package/dist/{generators → server/generators}/index.d.ts +1 -2
  41. package/dist/{generators → server/generators}/index.js +169 -75
  42. package/dist/server/generators/index.js.map +1 -0
  43. package/dist/server/labels/index.d.ts +1 -0
  44. package/dist/{labels → server/labels}/index.js +1 -1
  45. package/dist/server/labels/index.js.map +1 -0
  46. package/dist/{repositories → server/repositories}/index.js +11 -11
  47. package/dist/server/repositories/index.js.map +1 -0
  48. package/dist/{routes → server/routes}/labels/[id]/index.js +20 -20
  49. package/dist/server/routes/labels/[id]/index.js.map +1 -0
  50. package/dist/{routes → server/routes}/labels/by-key/[key]/index.js +20 -20
  51. package/dist/server/routes/labels/by-key/[key]/index.js.map +1 -0
  52. package/dist/{routes → server/routes}/labels/index.d.ts +2 -2
  53. package/dist/{routes → server/routes}/labels/index.js +21 -22
  54. package/dist/server/routes/labels/index.js.map +1 -0
  55. package/dist/{routes → server/routes}/published-cache/index.js +14 -14
  56. package/dist/server/routes/published-cache/index.js.map +1 -0
  57. package/dist/{routes → server/routes}/values/[labelId]/[version]/index.js +16 -16
  58. package/dist/server/routes/values/[labelId]/[version]/index.js.map +1 -0
  59. package/dist/{routes → server/routes}/values/[labelId]/index.js +16 -16
  60. package/dist/server/routes/values/[labelId]/index.js.map +1 -0
  61. package/dist/server.d.ts +76 -7
  62. package/dist/server.js +1601 -42
  63. package/dist/server.js.map +1 -1
  64. package/package.json +37 -35
  65. package/dist/contracts/labels.js.map +0 -1
  66. package/dist/contracts/published-cache.js.map +0 -1
  67. package/dist/contracts/values.js.map +0 -1
  68. package/dist/entities/cms-audit-logs.js.map +0 -1
  69. package/dist/entities/cms-draft-cache.js.map +0 -1
  70. package/dist/entities/cms-label-values.js.map +0 -1
  71. package/dist/entities/cms-label-versions.js.map +0 -1
  72. package/dist/entities/cms-labels.js.map +0 -1
  73. package/dist/entities/cms-published-cache.js.map +0 -1
  74. package/dist/entities/index.js.map +0 -1
  75. package/dist/generators/index.js.map +0 -1
  76. package/dist/label-sync-generator-lQrcVfja.d.ts +0 -36
  77. package/dist/labels/index.d.ts +0 -34
  78. package/dist/labels/index.js.map +0 -1
  79. package/dist/repositories/index.js.map +0 -1
  80. package/dist/routes/labels/[id]/index.js.map +0 -1
  81. package/dist/routes/labels/by-key/[key]/index.js.map +0 -1
  82. package/dist/routes/labels/index.js.map +0 -1
  83. package/dist/routes/published-cache/index.js.map +0 -1
  84. package/dist/routes/values/[labelId]/[version]/index.js.map +0 -1
  85. package/dist/routes/values/[labelId]/index.js.map +0 -1
  86. package/dist/store.d.ts +0 -81
  87. package/dist/store.js +0 -403
  88. package/dist/store.js.map +0 -1
  89. package/dist/types.js +0 -1
  90. package/dist/types.js.map +0 -1
  91. package/dist/{entities → server/entities}/cms-audit-logs.d.ts +0 -0
  92. package/dist/{entities → server/entities}/cms-draft-cache.d.ts +0 -0
  93. package/dist/{entities → server/entities}/cms-label-values.d.ts +0 -0
  94. package/dist/{entities → server/entities}/cms-label-versions.d.ts +0 -0
  95. package/dist/{entities → server/entities}/cms-labels.d.ts +0 -0
  96. package/dist/{entities → server/entities}/cms-published-cache.d.ts +0 -0
  97. package/dist/{entities → server/entities}/index.d.ts +0 -0
  98. package/dist/{repositories → server/repositories}/index.d.ts +14 -14
  99. /package/dist/{routes → server/routes}/labels/_id_/index.d.ts +0 -0
  100. /package/dist/{routes → server/routes}/labels/by-key/_key_/index.d.ts +0 -0
  101. /package/dist/{routes → server/routes}/published-cache/index.d.ts +0 -0
  102. /package/dist/{routes → server/routes}/values/_labelId_/_version_/index.d.ts +0 -0
  103. /package/dist/{routes → server/routes}/values/_labelId_/index.d.ts +0 -0
package/dist/api.js ADDED
@@ -0,0 +1,364 @@
1
+ // src/api/index.ts
2
+ import { client as client5 } from "@spfn/core/client";
3
+
4
+ // src/api/CmsLabels.ts
5
+ import { client } from "@spfn/core/client";
6
+
7
+ // src/lib/contracts/labels.ts
8
+ import { Type } from "@sinclair/typebox";
9
+ var getLabelsContract = {
10
+ method: "GET",
11
+ path: "/labels",
12
+ query: Type.Object({
13
+ section: Type.Optional(Type.String({ description: "\uC139\uC158\uC73C\uB85C \uD544\uD130\uB9C1 (\uC608: home, why-futureplay)" })),
14
+ limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100, default: 20, description: "\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218" })),
15
+ offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: "\uC2DC\uC791 \uC624\uD504\uC14B" }))
16
+ }),
17
+ response: Type.Object({
18
+ labels: Type.Array(Type.Object({
19
+ id: Type.Number(),
20
+ key: Type.String(),
21
+ section: Type.String(),
22
+ type: Type.String(),
23
+ publishedVersion: Type.Union([Type.Number(), Type.Null()]),
24
+ createdBy: Type.Union([Type.String(), Type.Null()]),
25
+ createdAt: Type.String(),
26
+ updatedAt: Type.String()
27
+ })),
28
+ total: Type.Number(),
29
+ limit: Type.Number(),
30
+ offset: Type.Number()
31
+ })
32
+ };
33
+ var createLabelContract = {
34
+ method: "POST",
35
+ path: "/labels",
36
+ body: Type.Object({
37
+ key: Type.String({
38
+ description: "\uACE0\uC720 \uD0A4 (\uC608: home.hero.title)",
39
+ pattern: "^[a-z0-9-]+\\.[a-z0-9-]+\\.[a-z0-9-]+$"
40
+ }),
41
+ section: Type.String({
42
+ description: "\uC139\uC158 \uC774\uB984 (\uC608: home, why-futureplay)",
43
+ pattern: "^[a-z0-9-]+$"
44
+ }),
45
+ type: Type.Union([
46
+ Type.Literal("text"),
47
+ Type.Literal("image"),
48
+ Type.Literal("video"),
49
+ Type.Literal("file"),
50
+ Type.Literal("object")
51
+ ], { description: "\uAC12 \uD0C0\uC785" }),
52
+ createdBy: Type.Optional(Type.String({ description: "\uC0DD\uC131\uC790 ID" }))
53
+ }),
54
+ response: Type.Union([
55
+ Type.Object({
56
+ id: Type.Number(),
57
+ key: Type.String(),
58
+ section: Type.String(),
59
+ type: Type.String(),
60
+ publishedVersion: Type.Union([Type.Number(), Type.Null()]),
61
+ createdBy: Type.Union([Type.String(), Type.Null()]),
62
+ createdAt: Type.String(),
63
+ updatedAt: Type.String()
64
+ }),
65
+ Type.Object({
66
+ error: Type.String(),
67
+ key: Type.Optional(Type.String())
68
+ })
69
+ ])
70
+ };
71
+ var getLabelContract = {
72
+ method: "GET",
73
+ path: "/labels/:id",
74
+ params: Type.Object({
75
+ id: Type.String({ description: "\uB77C\uBCA8 ID" })
76
+ }),
77
+ response: Type.Union([
78
+ Type.Object({
79
+ id: Type.Number(),
80
+ key: Type.String(),
81
+ section: Type.String(),
82
+ type: Type.String(),
83
+ publishedVersion: Type.Union([Type.Number(), Type.Null()]),
84
+ createdBy: Type.Union([Type.String(), Type.Null()]),
85
+ createdAt: Type.String(),
86
+ updatedAt: Type.String()
87
+ }),
88
+ Type.Object({
89
+ error: Type.String()
90
+ })
91
+ ])
92
+ };
93
+ var updateLabelContract = {
94
+ method: "PATCH",
95
+ path: "/labels/:id",
96
+ params: Type.Object({
97
+ id: Type.String({ description: "\uB77C\uBCA8 ID" })
98
+ }),
99
+ body: Type.Object({
100
+ section: Type.Optional(Type.String({ description: "\uC139\uC158 \uBCC0\uACBD" })),
101
+ type: Type.Optional(Type.Union([
102
+ Type.Literal("text"),
103
+ Type.Literal("image"),
104
+ Type.Literal("video"),
105
+ Type.Literal("file"),
106
+ Type.Literal("object")
107
+ ]))
108
+ }),
109
+ response: Type.Union([
110
+ Type.Object({
111
+ id: Type.Number(),
112
+ key: Type.String(),
113
+ section: Type.String(),
114
+ type: Type.String(),
115
+ publishedVersion: Type.Union([Type.Number(), Type.Null()]),
116
+ createdBy: Type.Union([Type.String(), Type.Null()]),
117
+ createdAt: Type.String(),
118
+ updatedAt: Type.String()
119
+ }),
120
+ Type.Object({
121
+ error: Type.String()
122
+ })
123
+ ])
124
+ };
125
+ var deleteLabelContract = {
126
+ method: "DELETE",
127
+ path: "/labels/:id",
128
+ params: Type.Object({
129
+ id: Type.String({ description: "\uB77C\uBCA8 ID" })
130
+ }),
131
+ response: Type.Union([
132
+ Type.Object({
133
+ success: Type.Boolean(),
134
+ id: Type.Number()
135
+ }),
136
+ Type.Object({
137
+ error: Type.String()
138
+ })
139
+ ])
140
+ };
141
+ var getLabelByKeyContract = {
142
+ method: "GET",
143
+ path: "/labels/by-key/:key",
144
+ params: Type.Object({
145
+ key: Type.String({ description: "\uB77C\uBCA8 Key (\uC608: home.hero.title)" })
146
+ }),
147
+ response: Type.Union([
148
+ Type.Object({
149
+ id: Type.Number(),
150
+ key: Type.String(),
151
+ section: Type.String(),
152
+ type: Type.String(),
153
+ publishedVersion: Type.Union([Type.Number(), Type.Null()]),
154
+ createdBy: Type.Union([Type.String(), Type.Null()]),
155
+ createdAt: Type.String(),
156
+ updatedAt: Type.String()
157
+ }),
158
+ Type.Object({
159
+ error: Type.String(),
160
+ key: Type.Optional(Type.String())
161
+ })
162
+ ])
163
+ };
164
+
165
+ // src/api/CmsLabels.ts
166
+ var CmsLabels = {
167
+ /**
168
+ * GET /_cms/labels
169
+ */
170
+ get: (options) => client.call(getLabelsContract, options),
171
+ /**
172
+ * POST /_cms/labels
173
+ */
174
+ post: (options) => client.call(createLabelContract, options),
175
+ /**
176
+ * GET /_cms/labels/:id
177
+ */
178
+ getById: (options) => client.call(getLabelContract, options),
179
+ /**
180
+ * PATCH /_cms/labels/:id
181
+ */
182
+ update: (options) => client.call(updateLabelContract, options),
183
+ /**
184
+ * DELETE /_cms/labels/:id
185
+ */
186
+ delete: (options) => client.call(deleteLabelContract, options)
187
+ };
188
+
189
+ // src/api/CmsLabelsByKey.ts
190
+ import { client as client2 } from "@spfn/core/client";
191
+ var CmsLabelsByKey = {
192
+ /**
193
+ * GET /_cms/labels/by-key/:key
194
+ */
195
+ getById: (options) => client2.call(getLabelByKeyContract, options)
196
+ };
197
+
198
+ // src/api/CmsPublishedCache.ts
199
+ import { client as client3 } from "@spfn/core/client";
200
+
201
+ // src/lib/contracts/published-cache.ts
202
+ import { Type as Type2 } from "@sinclair/typebox";
203
+ var SectionData = Type2.Object({
204
+ section: Type2.String(),
205
+ locale: Type2.String(),
206
+ content: Type2.Record(Type2.String(), Type2.Any()),
207
+ version: Type2.Number(),
208
+ publishedAt: Type2.Union([Type2.String(), Type2.Null()])
209
+ });
210
+ var getPublishedCacheContract = {
211
+ method: "GET",
212
+ path: "/published-cache",
213
+ query: Type2.Object({
214
+ sections: Type2.Union([
215
+ Type2.String({ description: "\uB2E8\uC77C \uC139\uC158 \uC774\uB984 (\uC608: home)" }),
216
+ Type2.Array(Type2.String(), { description: '\uC5EC\uB7EC \uC139\uC158 \uC774\uB984 (\uC608: ["home", "footer"])' })
217
+ ]),
218
+ locale: Type2.Optional(Type2.String({ default: "ko", description: "\uC5B8\uC5B4 \uCF54\uB4DC" }))
219
+ }),
220
+ response: Type2.Union([
221
+ // 성공: 항상 배열로 반환
222
+ Type2.Array(SectionData),
223
+ // 에러
224
+ Type2.Object({
225
+ error: Type2.String()
226
+ })
227
+ ])
228
+ };
229
+
230
+ // src/api/CmsPublishedCache.ts
231
+ var CmsPublishedCache = {
232
+ /**
233
+ * GET /_cms/published-cache
234
+ */
235
+ get: (options) => client3.call(getPublishedCacheContract, options)
236
+ };
237
+
238
+ // src/api/CmsValues.ts
239
+ import { client as client4 } from "@spfn/core/client";
240
+
241
+ // src/lib/contracts/values.ts
242
+ import { Type as Type3 } from "@sinclair/typebox";
243
+ var LabelValueSchema = Type3.Object({
244
+ type: Type3.Union([
245
+ Type3.Literal("text"),
246
+ Type3.Literal("image"),
247
+ Type3.Literal("video"),
248
+ Type3.Literal("file"),
249
+ Type3.Literal("object")
250
+ ]),
251
+ content: Type3.Optional(Type3.String()),
252
+ // text type
253
+ url: Type3.Optional(Type3.String()),
254
+ // image, video, file types
255
+ alt: Type3.Optional(Type3.String()),
256
+ // image type
257
+ width: Type3.Optional(Type3.Number()),
258
+ // image type
259
+ height: Type3.Optional(Type3.Number()),
260
+ // image type
261
+ thumbnail: Type3.Optional(Type3.String()),
262
+ // video type
263
+ duration: Type3.Optional(Type3.Number()),
264
+ // video type
265
+ filename: Type3.Optional(Type3.String()),
266
+ // file type
267
+ size: Type3.Optional(Type3.Number()),
268
+ // file type
269
+ fields: Type3.Optional(Type3.Any())
270
+ // object type - recursive structure
271
+ });
272
+ var saveValuesContract = {
273
+ method: "POST",
274
+ path: "/values/:labelId",
275
+ params: Type3.Object({
276
+ labelId: Type3.String({ description: "\uB77C\uBCA8 ID" })
277
+ }),
278
+ body: Type3.Object({
279
+ version: Type3.Number({ description: "\uBC84\uC804 \uBC88\uD638", minimum: 1 }),
280
+ values: Type3.Array(
281
+ Type3.Object({
282
+ locale: Type3.String({ description: "\uC5B8\uC5B4 \uCF54\uB4DC (ko, en, ja)", default: "ko" }),
283
+ breakpoint: Type3.Optional(Type3.Union([
284
+ Type3.Literal("sm"),
285
+ Type3.Literal("md"),
286
+ Type3.Literal("lg"),
287
+ Type3.Literal("xl"),
288
+ Type3.Literal("2xl"),
289
+ Type3.Null()
290
+ ], { description: "\uBC18\uC751\uD615 \uBE0C\uB808\uC774\uD06C\uD3EC\uC778\uD2B8" })),
291
+ value: LabelValueSchema
292
+ })
293
+ )
294
+ }),
295
+ response: Type3.Union([
296
+ Type3.Object({
297
+ success: Type3.Boolean(),
298
+ saved: Type3.Number(),
299
+ version: Type3.Number()
300
+ }),
301
+ Type3.Object({
302
+ error: Type3.String()
303
+ })
304
+ ])
305
+ };
306
+ var getValuesContract = {
307
+ method: "GET",
308
+ path: "/values/:labelId/:version",
309
+ params: Type3.Object({
310
+ labelId: Type3.String({ description: "\uB77C\uBCA8 ID" }),
311
+ version: Type3.String({ description: "\uBC84\uC804 \uBC88\uD638" })
312
+ }),
313
+ query: Type3.Object({
314
+ locale: Type3.Optional(Type3.String({ description: "\uC5B8\uC5B4 \uCF54\uB4DC (ko, en, ja)" })),
315
+ breakpoint: Type3.Optional(Type3.String({ description: "\uBC18\uC751\uD615 \uBE0C\uB808\uC774\uD06C\uD3EC\uC778\uD2B8" }))
316
+ }),
317
+ response: Type3.Union([
318
+ Type3.Object({
319
+ labelId: Type3.Number(),
320
+ version: Type3.Number(),
321
+ values: Type3.Array(
322
+ Type3.Object({
323
+ id: Type3.Number(),
324
+ locale: Type3.String(),
325
+ breakpoint: Type3.Union([Type3.String(), Type3.Null()]),
326
+ value: Type3.Any(),
327
+ createdAt: Type3.String()
328
+ })
329
+ )
330
+ }),
331
+ Type3.Object({
332
+ error: Type3.String()
333
+ })
334
+ ])
335
+ };
336
+
337
+ // src/api/CmsValues.ts
338
+ var CmsValues = {
339
+ /**
340
+ * POST /_cms/values/:labelId
341
+ */
342
+ post: (options) => client4.call(saveValuesContract, options),
343
+ /**
344
+ * GET /_cms/values/:labelId/:version
345
+ */
346
+ getById: (options) => client4.call(getValuesContract, options)
347
+ };
348
+
349
+ // src/api/index.ts
350
+ var cmsApi = {
351
+ cmsLabels: CmsLabels,
352
+ cmsLabelsByKey: CmsLabelsByKey,
353
+ cmsPublishedCache: CmsPublishedCache,
354
+ cmsValues: CmsValues
355
+ };
356
+ export {
357
+ CmsLabels,
358
+ CmsLabelsByKey,
359
+ CmsPublishedCache,
360
+ CmsValues,
361
+ client5 as client,
362
+ cmsApi
363
+ };
364
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/index.ts","../src/api/CmsLabels.ts","../src/lib/contracts/labels.ts","../src/api/CmsLabelsByKey.ts","../src/api/CmsPublishedCache.ts","../src/lib/contracts/published-cache.ts","../src/api/CmsValues.ts","../src/lib/contracts/values.ts"],"sourcesContent":["/**\n * Auto-generated API Client\n *\n * Generated by @spfn/core codegen\n * DO NOT EDIT MANUALLY\n *\n * @generated 2025-11-01T16:47:27.111Z\n */\n\nexport { client } from '@spfn/core/client';\n\nexport * from './CmsLabels.js';\nexport * from './CmsLabelsByKey.js';\nexport * from './CmsPublishedCache.js';\nexport * from './CmsValues.js';\n\nimport { CmsLabels } from './CmsLabels.js';\nimport { CmsLabelsByKey } from './CmsLabelsByKey.js';\nimport { CmsPublishedCache } from './CmsPublishedCache.js';\nimport { CmsValues } from './CmsValues.js';\n\n/**\n * Type-safe API client\n */\nexport const cmsApi = {\n cmsLabels: CmsLabels,\n cmsLabelsByKey: CmsLabelsByKey,\n cmsPublishedCache: CmsPublishedCache,\n cmsValues: CmsValues\n} as const;\n","/**\n * Auto-generated API Client\n *\n * Generated by @spfn/core codegen\n * DO NOT EDIT MANUALLY\n *\n * @generated 2025-11-01T16:47:27.109Z\n */\n\nimport { client } from '@spfn/core/client';\nimport type { InferContract } from '@spfn/core';\n\nimport { getLabelsContract, createLabelContract, getLabelContract, updateLabelContract, deleteLabelContract } from '@/lib/contracts/labels';\n\n// ============================================\n// Types\n// ============================================\n\nexport type GetLabelsResponse = InferContract<typeof getLabelsContract>['response'];\nexport type GetLabelsQuery = InferContract<typeof getLabelsContract>['query'];\n\nexport type CreateLabelResponse = InferContract<typeof createLabelContract>['response'];\nexport type CreateLabelBody = InferContract<typeof createLabelContract>['body'];\n\nexport type GetLabelResponse = InferContract<typeof getLabelContract>['response'];\nexport type GetLabelParams = InferContract<typeof getLabelContract>['params'];\n\nexport type UpdateLabelResponse = InferContract<typeof updateLabelContract>['response'];\nexport type UpdateLabelParams = InferContract<typeof updateLabelContract>['params'];\nexport type UpdateLabelBody = InferContract<typeof updateLabelContract>['body'];\n\nexport type DeleteLabelResponse = InferContract<typeof deleteLabelContract>['response'];\nexport type DeleteLabelParams = InferContract<typeof deleteLabelContract>['params'];\n\n/**\n * CmsLabels API\n */\nexport const CmsLabels = {\n /**\n * GET /_cms/labels\n */\n get: (options: { query?: GetLabelsQuery }) => client.call(getLabelsContract, options),\n /**\n * POST /_cms/labels\n */\n post: (options: { body: CreateLabelBody }) => client.call(createLabelContract, options),\n /**\n * GET /_cms/labels/:id\n */\n getById: (options: { params: GetLabelParams }) => client.call(getLabelContract, options),\n /**\n * PATCH /_cms/labels/:id\n */\n update: (options: { params: UpdateLabelParams, body: UpdateLabelBody }) => client.call(updateLabelContract, options),\n /**\n * DELETE /_cms/labels/:id\n */\n delete: (options: { params: DeleteLabelParams }) => client.call(deleteLabelContract, options),\n} as const;\n","import { Type } from '@sinclair/typebox';\nimport type { RouteContract } from '@spfn/core/route';\n\n/**\n * CMS Labels Contracts\n *\n * 라벨 메타데이터 관리 API\n */\n\n/**\n * GET /labels - 라벨 목록 조회\n * Final path: /_cms/labels (prefix added from package.json)\n */\nexport const getLabelsContract = {\n method: 'GET' as const,\n path: '/labels',\n query: Type.Object({\n section: Type.Optional(Type.String({ description: '섹션으로 필터링 (예: home, why-futureplay)' })),\n limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100, default: 20, description: '페이지당 항목 수' })),\n offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: '시작 오프셋' }))\n }),\n response: Type.Object({\n labels: Type.Array(Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n })),\n total: Type.Number(),\n limit: Type.Number(),\n offset: Type.Number()\n })\n} as const satisfies RouteContract;\n\n/**\n * POST /labels - 새 라벨 생성\n */\nexport const createLabelContract = {\n method: 'POST' as const,\n path: '/labels',\n body: Type.Object({\n key: Type.String({\n description: '고유 키 (예: home.hero.title)',\n pattern: '^[a-z0-9-]+\\\\.[a-z0-9-]+\\\\.[a-z0-9-]+$'\n }),\n section: Type.String({\n description: '섹션 이름 (예: home, why-futureplay)',\n pattern: '^[a-z0-9-]+$'\n }),\n type: Type.Union([\n Type.Literal('text'),\n Type.Literal('image'),\n Type.Literal('video'),\n Type.Literal('file'),\n Type.Literal('object')\n ], { description: '값 타입' }),\n createdBy: Type.Optional(Type.String({ description: '생성자 ID' }))\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String(),\n key: Type.Optional(Type.String())\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * GET /labels/:id - 라벨 단건 조회\n */\nexport const getLabelContract = {\n method: 'GET' as const,\n path: '/labels/:id',\n params: Type.Object({\n id: Type.String({ description: '라벨 ID' })\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * PATCH /labels/:id - 라벨 메타데이터 수정\n */\nexport const updateLabelContract = {\n method: 'PATCH' as const,\n path: '/labels/:id',\n params: Type.Object({\n id: Type.String({ description: '라벨 ID' })\n }),\n body: Type.Object({\n section: Type.Optional(Type.String({ description: '섹션 변경' })),\n type: Type.Optional(Type.Union([\n Type.Literal('text'),\n Type.Literal('image'),\n Type.Literal('video'),\n Type.Literal('file'),\n Type.Literal('object')\n ]))\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * DELETE /labels/:id - 라벨 삭제\n */\nexport const deleteLabelContract = {\n method: 'DELETE' as const,\n path: '/labels/:id',\n params: Type.Object({\n id: Type.String({ description: '라벨 ID' })\n }),\n response: Type.Union([\n Type.Object({\n success: Type.Boolean(),\n id: Type.Number()\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * GET /labels/by-key/:key - Key로 라벨 조회\n */\nexport const getLabelByKeyContract = {\n method: 'GET' as const,\n path: '/labels/by-key/:key',\n params: Type.Object({\n key: Type.String({ description: '라벨 Key (예: home.hero.title)' })\n }),\n response: Type.Union([\n Type.Object({\n id: Type.Number(),\n key: Type.String(),\n section: Type.String(),\n type: Type.String(),\n publishedVersion: Type.Union([Type.Number(), Type.Null()]),\n createdBy: Type.Union([Type.String(), Type.Null()]),\n createdAt: Type.String(),\n updatedAt: Type.String()\n }),\n Type.Object({\n error: Type.String(),\n key: Type.Optional(Type.String())\n })\n ])\n} as const satisfies RouteContract;","/**\n * Auto-generated API Client\n *\n * Generated by @spfn/core codegen\n * DO NOT EDIT MANUALLY\n *\n * @generated 2025-11-01T16:47:27.110Z\n */\n\nimport { client } from '@spfn/core/client';\nimport type { InferContract } from '@spfn/core';\n\nimport { getLabelByKeyContract } from '@/lib/contracts/labels';\n\n// ============================================\n// Types\n// ============================================\n\nexport type GetLabelByKeyResponse = InferContract<typeof getLabelByKeyContract>['response'];\nexport type GetLabelByKeyParams = InferContract<typeof getLabelByKeyContract>['params'];\n\n/**\n * CmsLabelsByKey API\n */\nexport const CmsLabelsByKey = {\n /**\n * GET /_cms/labels/by-key/:key\n */\n getById: (options: { params: GetLabelByKeyParams }) => client.call(getLabelByKeyContract, options),\n} as const;\n","/**\n * Auto-generated API Client\n *\n * Generated by @spfn/core codegen\n * DO NOT EDIT MANUALLY\n *\n * @generated 2025-11-01T16:47:27.111Z\n */\n\nimport { client } from '@spfn/core/client';\nimport type { InferContract } from '@spfn/core';\n\nimport { getPublishedCacheContract } from '@/lib/contracts/published-cache';\n\n// ============================================\n// Types\n// ============================================\n\nexport type GetPublishedCacheResponse = InferContract<typeof getPublishedCacheContract>['response'];\nexport type GetPublishedCacheQuery = InferContract<typeof getPublishedCacheContract>['query'];\n\n/**\n * CmsPublishedCache API\n */\nexport const CmsPublishedCache = {\n /**\n * GET /_cms/published-cache\n */\n get: (options: { query?: GetPublishedCacheQuery }) => client.call(getPublishedCacheContract, options),\n} as const;\n","import { Type } from '@sinclair/typebox';\nimport type { RouteContract } from '@spfn/core/route';\n\nconst SectionData = Type.Object({\n section: Type.String(),\n locale: Type.String(),\n content: Type.Record(Type.String(), Type.Any()),\n version: Type.Number(),\n publishedAt: Type.Union([Type.String(), Type.Null()]),\n});\n\n/**\n * GET /published-cache\n * 발행된 콘텐츠 캐시 조회 (단일 또는 여러 섹션)\n * Final path: /_cms/published-cache (prefix added from package.json)\n */\nexport const getPublishedCacheContract = {\n method: 'GET' as const,\n path: '/published-cache',\n query: Type.Object({\n sections: Type.Union([\n Type.String({ description: '단일 섹션 이름 (예: home)' }),\n Type.Array(Type.String(), { description: '여러 섹션 이름 (예: [\"home\", \"footer\"])' })\n ]),\n locale: Type.Optional(Type.String({ default: 'ko', description: '언어 코드' })),\n }),\n response: Type.Union([\n // 성공: 항상 배열로 반환\n Type.Array(SectionData),\n // 에러\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;","/**\n * Auto-generated API Client\n *\n * Generated by @spfn/core codegen\n * DO NOT EDIT MANUALLY\n *\n * @generated 2025-11-01T16:47:27.111Z\n */\n\nimport { client } from '@spfn/core/client';\nimport type { InferContract } from '@spfn/core';\n\nimport { saveValuesContract, getValuesContract } from '@/lib/contracts/values';\n\n// ============================================\n// Types\n// ============================================\n\nexport type SaveValuesResponse = InferContract<typeof saveValuesContract>['response'];\nexport type SaveValuesParams = InferContract<typeof saveValuesContract>['params'];\nexport type SaveValuesBody = InferContract<typeof saveValuesContract>['body'];\n\nexport type GetValuesResponse = InferContract<typeof getValuesContract>['response'];\nexport type GetValuesQuery = InferContract<typeof getValuesContract>['query'];\nexport type GetValuesParams = InferContract<typeof getValuesContract>['params'];\n\n/**\n * CmsValues API\n */\nexport const CmsValues = {\n /**\n * POST /_cms/values/:labelId\n */\n post: (options: { params: SaveValuesParams, body: SaveValuesBody }) => client.call(saveValuesContract, options),\n /**\n * GET /_cms/values/:labelId/:version\n */\n getById: (options: { params: GetValuesParams, query?: GetValuesQuery }) => client.call(getValuesContract, options),\n} as const;\n","import { Type } from '@sinclair/typebox';\nimport type { RouteContract } from '@spfn/core/route';\n\n/**\n * Label Value 타입 정의\n */\nconst LabelValueSchema = Type.Object({\n type: Type.Union([\n Type.Literal('text'),\n Type.Literal('image'),\n Type.Literal('video'),\n Type.Literal('file'),\n Type.Literal('object')\n ]),\n content: Type.Optional(Type.String()), // text type\n url: Type.Optional(Type.String()), // image, video, file types\n alt: Type.Optional(Type.String()), // image type\n width: Type.Optional(Type.Number()), // image type\n height: Type.Optional(Type.Number()), // image type\n thumbnail: Type.Optional(Type.String()), // video type\n duration: Type.Optional(Type.Number()), // video type\n filename: Type.Optional(Type.String()), // file type\n size: Type.Optional(Type.Number()), // file type\n fields: Type.Optional(Type.Any()) // object type - recursive structure\n});\n\n/**\n * POST /values/:labelId - 라벨 값 저장\n * Final path: /_cms/values/:labelId (prefix added from package.json)\n */\nexport const saveValuesContract = {\n method: 'POST' as const,\n path: '/values/:labelId',\n params: Type.Object({\n labelId: Type.String({ description: '라벨 ID' })\n }),\n body: Type.Object({\n version: Type.Number({ description: '버전 번호', minimum: 1 }),\n values: Type.Array(\n Type.Object({\n locale: Type.String({ description: '언어 코드 (ko, en, ja)', default: 'ko' }),\n breakpoint: Type.Optional(Type.Union([\n Type.Literal('sm'),\n Type.Literal('md'),\n Type.Literal('lg'),\n Type.Literal('xl'),\n Type.Literal('2xl'),\n Type.Null()\n ], { description: '반응형 브레이크포인트' })),\n value: LabelValueSchema\n })\n )\n }),\n response: Type.Union([\n Type.Object({\n success: Type.Boolean(),\n saved: Type.Number(),\n version: Type.Number()\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * GET /values/:labelId/:version - 특정 버전의 값 조회\n * Final path: /_cms/values/:labelId/:version (prefix added from package.json)\n */\nexport const getValuesContract = {\n method: 'GET' as const,\n path: '/values/:labelId/:version',\n params: Type.Object({\n labelId: Type.String({ description: '라벨 ID' }),\n version: Type.String({ description: '버전 번호' })\n }),\n query: Type.Object({\n locale: Type.Optional(Type.String({ description: '언어 코드 (ko, en, ja)' })),\n breakpoint: Type.Optional(Type.String({ description: '반응형 브레이크포인트' }))\n }),\n response: Type.Union([\n Type.Object({\n labelId: Type.Number(),\n version: Type.Number(),\n values: Type.Array(\n Type.Object({\n id: Type.Number(),\n locale: Type.String(),\n breakpoint: Type.Union([Type.String(), Type.Null()]),\n value: Type.Any(),\n createdAt: Type.String()\n })\n )\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;"],"mappings":"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","names":["client","client","client","client","Type","client","client","Type","client"]}
package/dist/client.d.ts CHANGED
@@ -1,10 +1,117 @@
1
- import { InferContract } from '@spfn/core';
2
- import { getLabelsContract, getLabelContract, createLabelContract, updateLabelContract, deleteLabelContract } from './contracts/labels.js';
3
- import { getPublishedCacheContract } from './contracts/published-cache.js';
4
- export { useCmsStore, useSection, useSections } from './store.js';
5
- import { SectionAPI } from './server.js';
6
- import '@sinclair/typebox';
7
- import 'zustand';
1
+ import { SectionData, SectionAPI } from './server.js';
2
+ import * as zustand from 'zustand';
3
+ export { L as LOCALE_COOKIE_KEY, d as LOCALE_INFO_MAP, e as LocaleInfo, S as SupportedLocale, c as getDialCode, b as getFlag, f as getLocale, g as getLocaleInfo, j as getLocaleWithInfo, h as getLocales, k as getLocalesWithInfo, a as getSupportedLocales, i as isRTL, s as setLocale } from './actions-CwvmPG0e.js';
4
+ import './index-Dh5FjWzR.js';
5
+ import './server/repositories/index.js';
6
+ import './server/entities/cms-labels.js';
7
+ import 'drizzle-orm/pg-core';
8
+ import './server/entities/cms-label-values.js';
9
+ import './server/entities/cms-draft-cache.js';
10
+ import './server/entities/cms-published-cache.js';
11
+ import './server/entities/cms-label-versions.js';
12
+ import './server/entities/cms-audit-logs.js';
13
+ import './label-sync-generator-B0EmvtWM.js';
14
+ import '@spfn/core/codegen';
15
+
16
+ /**
17
+ * useSection Hook
18
+ *
19
+ * 클라이언트 컴포넌트에서 섹션 데이터 사용
20
+ */
21
+ /**
22
+ * 섹션 Hook (서버 API와 동일한 패턴)
23
+ *
24
+ * @param section - 섹션 이름
25
+ * @param options - 옵션 (autoLoad: 자동 로드 여부)
26
+ * @returns { t, data, loading }
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * 'use client';
31
+ * import { useSection } from '@spfn/cms/client';
32
+ *
33
+ * export function ClientComponent()
34
+ * {
35
+ * const { t } = useSection('home', { autoLoad: true });
36
+ * return <h1>{t('hero.title')}</h1>;
37
+ * }
38
+ * ```
39
+ */
40
+ declare function useSection(section: string, options?: {
41
+ autoLoad?: boolean;
42
+ locale?: string;
43
+ }): {
44
+ t: (key: string, defaultValue?: any, replace?: Record<string, string | number>) => any;
45
+ data: SectionData;
46
+ loading: boolean;
47
+ };
48
+
49
+ /**
50
+ * useSections Hook
51
+ *
52
+ * 여러 섹션을 한번에 사용
53
+ */
54
+ /**
55
+ * 여러 섹션 Hook
56
+ *
57
+ * @param sectionNames - 섹션 이름 배열
58
+ * @returns { [section]: { t, data, loading }, ... }
59
+ *
60
+ * @example
61
+ * ```tsx
62
+ * 'use client';
63
+ * import { useSections } from '@spfn/cms/client';
64
+ *
65
+ * export function Component()
66
+ * {
67
+ * const sections = useSections(['home', 'layout']);
68
+ * return (
69
+ * <div>
70
+ * <h1>{sections.home.t('hero.title')}</h1>
71
+ * <p>{sections.layout.t('footer.copyright')}</p>
72
+ * </div>
73
+ * );
74
+ * }
75
+ * ```
76
+ */
77
+ declare function useSections(sectionNames: string[]): Record<string, {
78
+ t: (key: string, defaultValue?: any, replace?: Record<string, string | number>) => any;
79
+ data: SectionData;
80
+ loading: boolean;
81
+ }>;
82
+
83
+ interface CmsState {
84
+ /**
85
+ * 섹션별 데이터
86
+ * { 'home': { section: 'home', content: {...}, version: 1, ... }, ... }
87
+ */
88
+ sections: Record<string, SectionData>;
89
+ /**
90
+ * 로딩 상태
91
+ */
92
+ loading: Record<string, boolean>;
93
+ /**
94
+ * 섹션 데이터 설정 (서버에서 초기화용)
95
+ */
96
+ setSection: (section: string, data: SectionData) => void;
97
+ /**
98
+ * 여러 섹션 한번에 설정
99
+ */
100
+ setSections: (sections: Record<string, SectionData>) => void;
101
+ /**
102
+ * 섹션 비동기 로드
103
+ */
104
+ loadSection: (section: string, locale?: string) => Promise<void>;
105
+ /**
106
+ * 라벨 업데이트 (Draft Mode용)
107
+ */
108
+ updateLabel: (section: string, key: string, value: any) => void;
109
+ /**
110
+ * 초기화
111
+ */
112
+ reset: () => void;
113
+ }
114
+ declare const useCmsStore: zustand.UseBoundStore<zustand.StoreApi<CmsState>>;
8
115
 
9
116
  /**
10
117
  * CMS Store Initializer
@@ -36,137 +143,4 @@ interface InitCmsProps {
36
143
  */
37
144
  declare function InitCms({ sections }: InitCmsProps): null;
38
145
 
39
- /**
40
- * @spfn/cms/client
41
- *
42
- * Client Components Only
43
- * 클라이언트 컴포넌트 전용 (브라우저에서 실행)
44
- */
45
-
46
- /**
47
- * CMS API Client
48
- */
49
- declare const cmsApi: {
50
- /**
51
- * Labels API
52
- */
53
- readonly labels: {
54
- /**
55
- * GET /cms/labels
56
- * 라벨 목록 조회 (섹션 필터, 페이지네이션)
57
- */
58
- readonly list: (options?: {
59
- query?: InferContract<typeof getLabelsContract>["query"];
60
- }) => Promise<{
61
- limit: number;
62
- offset: number;
63
- labels: {
64
- section: string;
65
- id: number;
66
- key: string;
67
- type: string;
68
- publishedVersion: number | null;
69
- createdBy: string | null;
70
- createdAt: string;
71
- updatedAt: string;
72
- }[];
73
- total: number;
74
- }>;
75
- /**
76
- * GET /cms/labels/:id
77
- * 특정 라벨 조회
78
- */
79
- readonly getById: (options: {
80
- params: InferContract<typeof getLabelContract>["params"];
81
- }) => Promise<{
82
- section: string;
83
- id: number;
84
- key: string;
85
- type: string;
86
- publishedVersion: number | null;
87
- createdBy: string | null;
88
- createdAt: string;
89
- updatedAt: string;
90
- } | {
91
- error: string;
92
- }>;
93
- /**
94
- * POST /cms/labels
95
- * 새 라벨 생성
96
- */
97
- readonly create: (options: {
98
- body: InferContract<typeof createLabelContract>["body"];
99
- }) => Promise<{
100
- section: string;
101
- id: number;
102
- key: string;
103
- type: string;
104
- publishedVersion: number | null;
105
- createdBy: string | null;
106
- createdAt: string;
107
- updatedAt: string;
108
- } | {
109
- key?: string | undefined;
110
- error: string;
111
- }>;
112
- /**
113
- * PATCH /cms/labels/:id
114
- * 라벨 업데이트
115
- */
116
- readonly update: (options: {
117
- params: InferContract<typeof updateLabelContract>["params"];
118
- body: InferContract<typeof updateLabelContract>["body"];
119
- }) => Promise<{
120
- section: string;
121
- id: number;
122
- key: string;
123
- type: string;
124
- publishedVersion: number | null;
125
- createdBy: string | null;
126
- createdAt: string;
127
- updatedAt: string;
128
- } | {
129
- error: string;
130
- }>;
131
- /**
132
- * DELETE /cms/labels/:id
133
- * 라벨 삭제
134
- */
135
- readonly delete: (options: {
136
- params: InferContract<typeof deleteLabelContract>["params"];
137
- }) => Promise<{
138
- id: number;
139
- success: boolean;
140
- } | {
141
- error: string;
142
- }>;
143
- };
144
- /**
145
- * Published Cache API
146
- */
147
- readonly publishedCache: {
148
- /**
149
- * GET /cms/published-cache
150
- * 발행된 콘텐츠 캐시 조회
151
- */
152
- readonly get: (options: {
153
- query: InferContract<typeof getPublishedCacheContract>["query"];
154
- }) => Promise<{
155
- section: string;
156
- locale: string;
157
- content: {
158
- [x: string]: any;
159
- };
160
- version: number;
161
- publishedAt: string | null;
162
- }[] | {
163
- error: string;
164
- }>;
165
- };
166
- };
167
- /**
168
- * Type exports
169
- */
170
- type CmsApi = typeof cmsApi;
171
-
172
- export { type CmsApi, InitCms, cmsApi };
146
+ export { InitCms, useCmsStore, useSection, useSections };