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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/README.md +320 -359
  2. package/dist/actions.d.ts +12 -6
  3. package/dist/actions.js +25 -10
  4. package/dist/actions.js.map +1 -1
  5. package/dist/config.d.ts +39 -0
  6. package/dist/config.js +39 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/errors.d.ts +149 -0
  9. package/dist/errors.js +164 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/index.d.ts +138 -20
  12. package/dist/index.js +212 -23
  13. package/dist/index.js.map +1 -1
  14. package/dist/server.d.ts +44 -81
  15. package/dist/server.js +610 -256
  16. package/dist/server.js.map +1 -1
  17. package/migrations/0000_medical_ozymandias.sql +54 -0
  18. package/migrations/meta/0000_snapshot.json +336 -0
  19. package/migrations/meta/_journal.json +13 -0
  20. package/package.json +54 -44
  21. package/dist/actions.d.ts.map +0 -1
  22. package/dist/client.d.ts +0 -138
  23. package/dist/client.d.ts.map +0 -1
  24. package/dist/client.js +0 -62
  25. package/dist/client.js.map +0 -1
  26. package/dist/cms.config.d.ts +0 -77
  27. package/dist/cms.config.d.ts.map +0 -1
  28. package/dist/cms.config.js +0 -111
  29. package/dist/cms.config.js.map +0 -1
  30. package/dist/entities/cms-audit-logs.d.ts +0 -213
  31. package/dist/entities/cms-audit-logs.d.ts.map +0 -1
  32. package/dist/entities/cms-audit-logs.js +0 -103
  33. package/dist/entities/cms-audit-logs.js.map +0 -1
  34. package/dist/entities/cms-draft-cache.d.ts +0 -188
  35. package/dist/entities/cms-draft-cache.d.ts.map +0 -1
  36. package/dist/entities/cms-draft-cache.js +0 -112
  37. package/dist/entities/cms-draft-cache.js.map +0 -1
  38. package/dist/entities/cms-label-values.d.ts +0 -192
  39. package/dist/entities/cms-label-values.d.ts.map +0 -1
  40. package/dist/entities/cms-label-values.js +0 -105
  41. package/dist/entities/cms-label-values.js.map +0 -1
  42. package/dist/entities/cms-label-versions.d.ts +0 -207
  43. package/dist/entities/cms-label-versions.d.ts.map +0 -1
  44. package/dist/entities/cms-label-versions.js +0 -80
  45. package/dist/entities/cms-label-versions.js.map +0 -1
  46. package/dist/entities/cms-labels.d.ts +0 -189
  47. package/dist/entities/cms-labels.d.ts.map +0 -1
  48. package/dist/entities/cms-labels.js +0 -48
  49. package/dist/entities/cms-labels.js.map +0 -1
  50. package/dist/entities/cms-published-cache.d.ts +0 -199
  51. package/dist/entities/cms-published-cache.d.ts.map +0 -1
  52. package/dist/entities/cms-published-cache.js +0 -103
  53. package/dist/entities/cms-published-cache.js.map +0 -1
  54. package/dist/entities/index.d.ts +0 -10
  55. package/dist/entities/index.d.ts.map +0 -1
  56. package/dist/entities/index.js +0 -10
  57. package/dist/entities/index.js.map +0 -1
  58. package/dist/generators/index.d.ts +0 -19
  59. package/dist/generators/index.d.ts.map +0 -1
  60. package/dist/generators/index.js +0 -19
  61. package/dist/generators/index.js.map +0 -1
  62. package/dist/generators/label-sync-generator.d.ts +0 -33
  63. package/dist/generators/label-sync-generator.d.ts.map +0 -1
  64. package/dist/generators/label-sync-generator.js +0 -86
  65. package/dist/generators/label-sync-generator.js.map +0 -1
  66. package/dist/helpers/locale.actions.d.ts +0 -132
  67. package/dist/helpers/locale.actions.d.ts.map +0 -1
  68. package/dist/helpers/locale.actions.js +0 -210
  69. package/dist/helpers/locale.actions.js.map +0 -1
  70. package/dist/helpers/locale.constants.d.ts +0 -10
  71. package/dist/helpers/locale.constants.d.ts.map +0 -1
  72. package/dist/helpers/locale.constants.js +0 -10
  73. package/dist/helpers/locale.constants.js.map +0 -1
  74. package/dist/helpers/locale.d.ts +0 -17
  75. package/dist/helpers/locale.d.ts.map +0 -1
  76. package/dist/helpers/locale.js +0 -20
  77. package/dist/helpers/locale.js.map +0 -1
  78. package/dist/helpers/sync.d.ts +0 -41
  79. package/dist/helpers/sync.d.ts.map +0 -1
  80. package/dist/helpers/sync.js +0 -309
  81. package/dist/helpers/sync.js.map +0 -1
  82. package/dist/index.d.ts.map +0 -1
  83. package/dist/init.d.ts +0 -31
  84. package/dist/init.d.ts.map +0 -1
  85. package/dist/init.js +0 -36
  86. package/dist/init.js.map +0 -1
  87. package/dist/labels/helpers.d.ts +0 -31
  88. package/dist/labels/helpers.d.ts.map +0 -1
  89. package/dist/labels/helpers.js +0 -60
  90. package/dist/labels/helpers.js.map +0 -1
  91. package/dist/labels/index.d.ts +0 -7
  92. package/dist/labels/index.d.ts.map +0 -1
  93. package/dist/labels/index.js +0 -7
  94. package/dist/labels/index.js.map +0 -1
  95. package/dist/repositories/cms-draft-cache.repository.d.ts +0 -62
  96. package/dist/repositories/cms-draft-cache.repository.d.ts.map +0 -1
  97. package/dist/repositories/cms-draft-cache.repository.js +0 -56
  98. package/dist/repositories/cms-draft-cache.repository.js.map +0 -1
  99. package/dist/repositories/cms-label-values.repository.d.ts +0 -32
  100. package/dist/repositories/cms-label-values.repository.d.ts.map +0 -1
  101. package/dist/repositories/cms-label-values.repository.js +0 -72
  102. package/dist/repositories/cms-label-values.repository.js.map +0 -1
  103. package/dist/repositories/cms-labels.repository.d.ts +0 -53
  104. package/dist/repositories/cms-labels.repository.d.ts.map +0 -1
  105. package/dist/repositories/cms-labels.repository.js +0 -77
  106. package/dist/repositories/cms-labels.repository.js.map +0 -1
  107. package/dist/repositories/cms-published-cache.repository.d.ts +0 -53
  108. package/dist/repositories/cms-published-cache.repository.d.ts.map +0 -1
  109. package/dist/repositories/cms-published-cache.repository.js +0 -54
  110. package/dist/repositories/cms-published-cache.repository.js.map +0 -1
  111. package/dist/repositories/index.d.ts +0 -8
  112. package/dist/repositories/index.d.ts.map +0 -1
  113. package/dist/repositories/index.js +0 -9
  114. package/dist/repositories/index.js.map +0 -1
  115. package/dist/routes/labels/[id]/contract.d.ts +0 -68
  116. package/dist/routes/labels/[id]/contract.d.ts.map +0 -1
  117. package/dist/routes/labels/[id]/contract.js +0 -84
  118. package/dist/routes/labels/[id]/contract.js.map +0 -1
  119. package/dist/routes/labels/[id]/index.d.ts +0 -10
  120. package/dist/routes/labels/[id]/index.d.ts.map +0 -1
  121. package/dist/routes/labels/[id]/index.js +0 -96
  122. package/dist/routes/labels/[id]/index.js.map +0 -1
  123. package/dist/routes/labels/by-key/[key]/contract.d.ts +0 -24
  124. package/dist/routes/labels/by-key/[key]/contract.d.ts.map +0 -1
  125. package/dist/routes/labels/by-key/[key]/contract.js +0 -28
  126. package/dist/routes/labels/by-key/[key]/contract.js.map +0 -1
  127. package/dist/routes/labels/by-key/[key]/index.d.ts +0 -8
  128. package/dist/routes/labels/by-key/[key]/index.d.ts.map +0 -1
  129. package/dist/routes/labels/by-key/[key]/index.js +0 -32
  130. package/dist/routes/labels/by-key/[key]/index.js.map +0 -1
  131. package/dist/routes/labels/contract.d.ts +0 -59
  132. package/dist/routes/labels/contract.d.ts.map +0 -1
  133. package/dist/routes/labels/contract.js +0 -75
  134. package/dist/routes/labels/contract.js.map +0 -1
  135. package/dist/routes/labels/index.d.ts +0 -10
  136. package/dist/routes/labels/index.d.ts.map +0 -1
  137. package/dist/routes/labels/index.js +0 -73
  138. package/dist/routes/labels/index.js.map +0 -1
  139. package/dist/routes/published-cache/contract.d.ts +0 -25
  140. package/dist/routes/published-cache/contract.d.ts.map +0 -1
  141. package/dist/routes/published-cache/contract.js +0 -35
  142. package/dist/routes/published-cache/contract.js.map +0 -1
  143. package/dist/routes/published-cache/index.d.ts +0 -8
  144. package/dist/routes/published-cache/index.d.ts.map +0 -1
  145. package/dist/routes/published-cache/index.js +0 -33
  146. package/dist/routes/published-cache/index.js.map +0 -1
  147. package/dist/routes/values/[labelId]/[version]/contract.d.ts +0 -29
  148. package/dist/routes/values/[labelId]/[version]/contract.d.ts.map +0 -1
  149. package/dist/routes/values/[labelId]/[version]/contract.js +0 -33
  150. package/dist/routes/values/[labelId]/[version]/contract.js.map +0 -1
  151. package/dist/routes/values/[labelId]/[version]/index.d.ts +0 -8
  152. package/dist/routes/values/[labelId]/[version]/index.d.ts.map +0 -1
  153. package/dist/routes/values/[labelId]/[version]/index.js +0 -45
  154. package/dist/routes/values/[labelId]/[version]/index.js.map +0 -1
  155. package/dist/routes/values/[labelId]/contract.d.ts +0 -38
  156. package/dist/routes/values/[labelId]/contract.d.ts.map +0 -1
  157. package/dist/routes/values/[labelId]/contract.js +0 -59
  158. package/dist/routes/values/[labelId]/contract.js.map +0 -1
  159. package/dist/routes/values/[labelId]/index.d.ts +0 -8
  160. package/dist/routes/values/[labelId]/index.d.ts.map +0 -1
  161. package/dist/routes/values/[labelId]/index.js +0 -42
  162. package/dist/routes/values/[labelId]/index.js.map +0 -1
  163. package/dist/server.d.ts.map +0 -1
  164. package/dist/store.d.ts +0 -87
  165. package/dist/store.d.ts.map +0 -1
  166. package/dist/store.js +0 -205
  167. package/dist/store.js.map +0 -1
  168. package/dist/types.d.ts +0 -74
  169. package/dist/types.d.ts.map +0 -1
  170. package/dist/types.js +0 -7
  171. package/dist/types.js.map +0 -1
package/dist/actions.d.ts CHANGED
@@ -1,9 +1,15 @@
1
1
  /**
2
- * @spfn/cms/actions
2
+ * Set user's preferred locale in cookie
3
3
  *
4
- * Server Actions
5
- * 서버/클라이언트 컴포넌트 양쪽에서 사용 가능한 Server Actions
4
+ * @param locale - Language code (e.g., 'ko', 'en', 'ja')
6
5
  */
7
- export { getLocale, setLocale, getLocales, } from './helpers/locale.actions.js';
8
- export { LOCALE_COOKIE_KEY } from './helpers/locale.constants.js';
9
- //# sourceMappingURL=actions.d.ts.map
6
+ declare function setLocale(locale: string): Promise<void>;
7
+ /**
8
+ * Get user's preferred locale from cookie
9
+ *
10
+ * @param defaultLocale - Default locale from labelConfig.defaultLocale
11
+ * @returns Language code (from cookie, or defaultLocale, or 'en')
12
+ */
13
+ declare function getLocale(defaultLocale?: string): Promise<string>;
14
+
15
+ export { getLocale, setLocale };
package/dist/actions.js CHANGED
@@ -1,11 +1,26 @@
1
- /**
2
- * @spfn/cms/actions
3
- *
4
- * Server Actions
5
- * 서버/클라이언트 컴포넌트 양쪽에서 사용 가능한 Server Actions
6
- */
7
- // Locale Server Actions
8
- export { getLocale, setLocale, getLocales, } from './helpers/locale.actions.js';
9
- // Locale Constants
10
- export { LOCALE_COOKIE_KEY } from './helpers/locale.constants.js';
1
+ "use server";
2
+
3
+ // src/actions.ts
4
+ import { cookies } from "next/headers";
5
+ var LOCALE_COOKIE_NAME = "cms-locale";
6
+ var LOCALE_MAX_AGE = 365 * 24 * 60 * 60;
7
+ async function setLocale(locale) {
8
+ const cookieStore = await cookies();
9
+ cookieStore.set(LOCALE_COOKIE_NAME, locale, {
10
+ httpOnly: true,
11
+ secure: process.env.NODE_ENV === "production",
12
+ sameSite: "lax",
13
+ maxAge: LOCALE_MAX_AGE,
14
+ path: "/"
15
+ });
16
+ }
17
+ async function getLocale(defaultLocale) {
18
+ const cookieStore = await cookies();
19
+ const localeCookie = cookieStore.get(LOCALE_COOKIE_NAME);
20
+ return localeCookie?.value ?? defaultLocale ?? "en";
21
+ }
22
+ export {
23
+ getLocale,
24
+ setLocale
25
+ };
11
26
  //# sourceMappingURL=actions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAwB;AACxB,OAAO,EACH,SAAS,EACT,SAAS,EACT,UAAU,GACb,MAAM,6BAA6B,CAAC;AAErC,mBAAmB;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"sources":["../src/actions.ts"],"sourcesContent":["\"use server\"\n\nimport { cookies } from 'next/headers';\n\nconst LOCALE_COOKIE_NAME = 'cms-locale';\nconst LOCALE_MAX_AGE = 365 * 24 * 60 * 60; // 1 year\n\n/**\n * Set user's preferred locale in cookie\n *\n * @param locale - Language code (e.g., 'ko', 'en', 'ja')\n */\nexport async function setLocale(locale: string): Promise<void>\n{\n const cookieStore = await cookies();\n\n cookieStore.set(LOCALE_COOKIE_NAME, locale, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n maxAge: LOCALE_MAX_AGE,\n path: '/',\n });\n}\n\n/**\n * Get user's preferred locale from cookie\n *\n * @param defaultLocale - Default locale from labelConfig.defaultLocale\n * @returns Language code (from cookie, or defaultLocale, or 'en')\n */\nexport async function getLocale(defaultLocale?: string): Promise<string>\n{\n const cookieStore = await cookies();\n const localeCookie = cookieStore.get(LOCALE_COOKIE_NAME);\n\n return localeCookie?.value ?? defaultLocale ?? 'en';\n}"],"mappings":";;;AAEA,SAAS,eAAe;AAExB,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB,MAAM,KAAK,KAAK;AAOvC,eAAsB,UAAU,QAChC;AACI,QAAM,cAAc,MAAM,QAAQ;AAElC,cAAY,IAAI,oBAAoB,QAAQ;AAAA,IACxC,UAAU;AAAA,IACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,IACjC,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,EACV,CAAC;AACL;AAQA,eAAsB,UAAU,eAChC;AACI,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,eAAe,YAAY,IAAI,kBAAkB;AAEvD,SAAO,cAAc,SAAS,iBAAiB;AACnD;","names":[]}
@@ -0,0 +1,39 @@
1
+ import * as _spfn_core_env from '@spfn/core/env';
2
+
3
+ /**
4
+ * Core Package Configuration
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { registry } from '@spfn/core/config';
9
+ *
10
+ * const env = registry.validate();
11
+ * console.log(env.DB_POOL_MAX);
12
+ * ```
13
+ *
14
+ * @module config
15
+ */
16
+ declare const env: _spfn_core_env.InferEnvType<{
17
+ SPFN_CMS_DEFAULT_LOCALE: {
18
+ description: string;
19
+ default: string;
20
+ required: boolean;
21
+ category: string;
22
+ examples: string[];
23
+ type: "string";
24
+ } & {
25
+ key: "SPFN_CMS_DEFAULT_LOCALE";
26
+ };
27
+ SPFN_CMS_DETECT_BROWSER_LANGUAGE: {
28
+ description: string;
29
+ default: boolean;
30
+ required: boolean;
31
+ category: string;
32
+ type: "boolean";
33
+ validator: (value: string) => boolean;
34
+ } & {
35
+ key: "SPFN_CMS_DETECT_BROWSER_LANGUAGE";
36
+ };
37
+ }>;
38
+
39
+ export { env };
package/dist/config.js ADDED
@@ -0,0 +1,39 @@
1
+ // src/config/index.ts
2
+ import { createEnvRegistry } from "@spfn/core/env";
3
+
4
+ // src/config/schema.ts
5
+ import {
6
+ defineEnvSchema,
7
+ envString,
8
+ envBoolean
9
+ } from "@spfn/core/env";
10
+ var cmsEnvSchema = defineEnvSchema({
11
+ // ============================================================================
12
+ // Locale Configuration
13
+ // ============================================================================
14
+ SPFN_CMS_DEFAULT_LOCALE: {
15
+ ...envString({
16
+ description: "[DEPRECATED] Use labelConfig.defaultLocale instead. Default language for CMS content (ISO 639-1 language code)",
17
+ default: "en",
18
+ required: false,
19
+ category: "cms",
20
+ examples: ["en", "ko", "ja", "zh", "es", "fr", "de"]
21
+ })
22
+ },
23
+ SPFN_CMS_DETECT_BROWSER_LANGUAGE: {
24
+ ...envBoolean({
25
+ description: "Automatically detect and use browser language for content localization",
26
+ default: true,
27
+ required: false,
28
+ category: "cms"
29
+ })
30
+ }
31
+ });
32
+
33
+ // src/config/index.ts
34
+ var registry = createEnvRegistry(cmsEnvSchema);
35
+ var env = registry.validate();
36
+ export {
37
+ env
38
+ };
39
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/index.ts","../src/config/schema.ts"],"sourcesContent":["/**\n * Core Package Configuration\n *\n * @example\n * ```typescript\n * import { registry } from '@spfn/core/config';\n *\n * const env = registry.validate();\n * console.log(env.DB_POOL_MAX);\n * ```\n *\n * @module config\n */\n\nimport { createEnvRegistry } from '@spfn/core/env';\nimport { cmsEnvSchema } from './schema';\n\n/**\n * Environment registry\n */\nconst registry = createEnvRegistry(cmsEnvSchema);\nexport const env = registry.validate();","/**\n * CMS Environment Variable Schema\n *\n * Centralized schema definition for all environment variables used in @spfn/cms.\n * This provides type safety, validation, and documentation for CMS configuration.\n *\n * @module config/schema\n */\n\nimport {\n defineEnvSchema,\n envString,\n envBoolean,\n} from '@spfn/core/env';\n\n/**\n * CMS environment variable schema\n *\n * Defines all CMS environment variables with:\n * - Type information\n * - Default values\n * - Validation rules\n * - Documentation\n *\n * @example\n * ```typescript\n * import { cmsEnvSchema } from '@spfn/cms/config';\n *\n * // Access schema information\n * console.log(cmsEnvSchema.SPFN_CMS_DEFAULT_LOCALE.description);\n * console.log(cmsEnvSchema.SPFN_CMS_DEFAULT_LOCALE.default);\n * ```\n */\nexport const cmsEnvSchema = defineEnvSchema({\n // ============================================================================\n // Locale Configuration\n // ============================================================================\n SPFN_CMS_DEFAULT_LOCALE: {\n ...envString({\n description: '[DEPRECATED] Use labelConfig.defaultLocale instead. Default language for CMS content (ISO 639-1 language code)',\n default: 'en',\n required: false,\n category: 'cms',\n examples: ['en', 'ko', 'ja', 'zh', 'es', 'fr', 'de'],\n }),\n },\n\n SPFN_CMS_DETECT_BROWSER_LANGUAGE: {\n ...envBoolean({\n description: 'Automatically detect and use browser language for content localization',\n default: true,\n required: false,\n category: 'cms',\n }),\n },\n});"],"mappings":";AAcA,SAAS,yBAAyB;;;ACLlC;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAoBA,IAAM,eAAe,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAIxC,yBAAyB;AAAA,IACrB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,IACvD,CAAC;AAAA,EACL;AAAA,EAEA,kCAAkC;AAAA,IAC9B,GAAG,WAAW;AAAA,MACV,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,IACd,CAAC;AAAA,EACL;AACJ,CAAC;;;ADnCD,IAAM,WAAW,kBAAkB,YAAY;AACxC,IAAM,MAAM,SAAS,SAAS;","names":[]}
@@ -0,0 +1,149 @@
1
+ import { NotFoundError, ConflictError, ValidationError, InternalServerError, ForbiddenError } from '@spfn/core/errors';
2
+
3
+ /**
4
+ * CMS Error Classes
5
+ *
6
+ * Custom error classes for CMS-specific scenarios
7
+ */
8
+
9
+ /**
10
+ * Label Not Found Error (404)
11
+ *
12
+ * Thrown when a CMS label does not exist
13
+ */
14
+ declare class LabelNotFoundError extends NotFoundError {
15
+ constructor(data?: {
16
+ labelKey?: string;
17
+ labelId?: number;
18
+ message?: string;
19
+ details?: Record<string, any>;
20
+ });
21
+ }
22
+ /**
23
+ * Label Value Not Found Error (404)
24
+ *
25
+ * Thrown when a CMS label value does not exist
26
+ */
27
+ declare class LabelValueNotFoundError extends NotFoundError {
28
+ constructor(data?: {
29
+ labelKey?: string;
30
+ locale?: string;
31
+ valueId?: number;
32
+ message?: string;
33
+ details?: Record<string, any>;
34
+ });
35
+ }
36
+ /**
37
+ * Locale Not Found Error (404)
38
+ *
39
+ * Thrown when requested locale does not exist in the system
40
+ */
41
+ declare class LocaleNotFoundError extends NotFoundError {
42
+ constructor(data?: {
43
+ locale?: string;
44
+ message?: string;
45
+ details?: Record<string, any>;
46
+ });
47
+ }
48
+ /**
49
+ * Published Cache Not Found Error (404)
50
+ *
51
+ * Thrown when published cache does not exist
52
+ */
53
+ declare class PublishedCacheNotFoundError extends NotFoundError {
54
+ constructor(data?: {
55
+ locale?: string;
56
+ message?: string;
57
+ details?: Record<string, any>;
58
+ });
59
+ }
60
+ /**
61
+ * Duplicate Label Error (409)
62
+ *
63
+ * Thrown when trying to create a label with existing key
64
+ */
65
+ declare class DuplicateLabelError extends ConflictError {
66
+ constructor(data?: {
67
+ labelKey?: string;
68
+ message?: string;
69
+ details?: Record<string, any>;
70
+ });
71
+ }
72
+ /**
73
+ * Duplicate Label Value Error (409)
74
+ *
75
+ * Thrown when trying to create a label value that already exists
76
+ */
77
+ declare class DuplicateLabelValueError extends ConflictError {
78
+ constructor(data?: {
79
+ labelKey?: string;
80
+ locale?: string;
81
+ message?: string;
82
+ details?: Record<string, any>;
83
+ });
84
+ }
85
+ /**
86
+ * Invalid Locale Error (400)
87
+ *
88
+ * Thrown when locale format is invalid or not supported
89
+ */
90
+ declare class InvalidLocaleError extends ValidationError {
91
+ constructor(data?: {
92
+ locale?: string;
93
+ message?: string;
94
+ details?: Record<string, any>;
95
+ });
96
+ }
97
+ /**
98
+ * Invalid Label Key Error (400)
99
+ *
100
+ * Thrown when label key format is invalid
101
+ */
102
+ declare class InvalidLabelKeyError extends ValidationError {
103
+ constructor(data?: {
104
+ labelKey?: string;
105
+ message?: string;
106
+ details?: Record<string, any>;
107
+ });
108
+ }
109
+ /**
110
+ * Invalid Published Cache Error (400)
111
+ *
112
+ * Thrown when published cache data is malformed or corrupted
113
+ */
114
+ declare class InvalidPublishedCacheError extends ValidationError {
115
+ constructor(data?: {
116
+ locale?: string;
117
+ reason?: string;
118
+ message?: string;
119
+ details?: Record<string, any>;
120
+ });
121
+ }
122
+ /**
123
+ * CMS Operation Failed Error (500)
124
+ *
125
+ * Thrown when CMS operation fails unexpectedly
126
+ */
127
+ declare class CMSOperationFailedError extends InternalServerError {
128
+ constructor(data?: {
129
+ operation?: string;
130
+ resource?: string;
131
+ message?: string;
132
+ details?: Record<string, any>;
133
+ });
134
+ }
135
+ /**
136
+ * Insufficient CMS Permissions Error (403)
137
+ *
138
+ * Thrown when user lacks required CMS permissions
139
+ */
140
+ declare class InsufficientCMSPermissionsError extends ForbiddenError {
141
+ constructor(data?: {
142
+ requiredPermissions?: string[];
143
+ resource?: string;
144
+ message?: string;
145
+ details?: Record<string, any>;
146
+ });
147
+ }
148
+
149
+ export { CMSOperationFailedError, DuplicateLabelError, DuplicateLabelValueError, InsufficientCMSPermissionsError, InvalidLabelKeyError, InvalidLocaleError, InvalidPublishedCacheError, LabelNotFoundError, LabelValueNotFoundError, LocaleNotFoundError, PublishedCacheNotFoundError };
package/dist/errors.js ADDED
@@ -0,0 +1,164 @@
1
+ // src/errors/cms-errors.ts
2
+ import {
3
+ ValidationError,
4
+ NotFoundError,
5
+ ConflictError,
6
+ ForbiddenError,
7
+ InternalServerError
8
+ } from "@spfn/core/errors";
9
+ var LabelNotFoundError = class extends NotFoundError {
10
+ constructor(data = {}) {
11
+ super({
12
+ message: data.message || "Label not found",
13
+ details: {
14
+ labelKey: data.labelKey,
15
+ labelId: data.labelId,
16
+ ...data.details
17
+ }
18
+ });
19
+ this.name = "LabelNotFoundError";
20
+ }
21
+ };
22
+ var LabelValueNotFoundError = class extends NotFoundError {
23
+ constructor(data = {}) {
24
+ super({
25
+ message: data.message || "Label value not found",
26
+ details: {
27
+ labelKey: data.labelKey,
28
+ locale: data.locale,
29
+ valueId: data.valueId,
30
+ ...data.details
31
+ }
32
+ });
33
+ this.name = "LabelValueNotFoundError";
34
+ }
35
+ };
36
+ var LocaleNotFoundError = class extends NotFoundError {
37
+ constructor(data = {}) {
38
+ super({
39
+ message: data.message || "Locale not found",
40
+ details: {
41
+ locale: data.locale,
42
+ ...data.details
43
+ }
44
+ });
45
+ this.name = "LocaleNotFoundError";
46
+ }
47
+ };
48
+ var PublishedCacheNotFoundError = class extends NotFoundError {
49
+ constructor(data = {}) {
50
+ super({
51
+ message: data.message || "Published cache not found",
52
+ details: {
53
+ locale: data.locale,
54
+ ...data.details
55
+ }
56
+ });
57
+ this.name = "PublishedCacheNotFoundError";
58
+ }
59
+ };
60
+ var DuplicateLabelError = class extends ConflictError {
61
+ constructor(data = {}) {
62
+ super({
63
+ message: data.message || "Label already exists",
64
+ details: {
65
+ labelKey: data.labelKey,
66
+ ...data.details
67
+ }
68
+ });
69
+ this.name = "DuplicateLabelError";
70
+ }
71
+ };
72
+ var DuplicateLabelValueError = class extends ConflictError {
73
+ constructor(data = {}) {
74
+ super({
75
+ message: data.message || "Label value already exists for this locale",
76
+ details: {
77
+ labelKey: data.labelKey,
78
+ locale: data.locale,
79
+ ...data.details
80
+ }
81
+ });
82
+ this.name = "DuplicateLabelValueError";
83
+ }
84
+ };
85
+ var InvalidLocaleError = class extends ValidationError {
86
+ constructor(data = {}) {
87
+ super({
88
+ message: data.message || "Invalid locale",
89
+ details: {
90
+ locale: data.locale,
91
+ ...data.details
92
+ }
93
+ });
94
+ this.name = "InvalidLocaleError";
95
+ }
96
+ };
97
+ var InvalidLabelKeyError = class extends ValidationError {
98
+ constructor(data = {}) {
99
+ super({
100
+ message: data.message || "Invalid label key format",
101
+ details: {
102
+ labelKey: data.labelKey,
103
+ ...data.details
104
+ }
105
+ });
106
+ this.name = "InvalidLabelKeyError";
107
+ }
108
+ };
109
+ var InvalidPublishedCacheError = class extends ValidationError {
110
+ constructor(data = {}) {
111
+ super({
112
+ message: data.message || "Invalid published cache data",
113
+ details: {
114
+ locale: data.locale,
115
+ reason: data.reason,
116
+ ...data.details
117
+ }
118
+ });
119
+ this.name = "InvalidPublishedCacheError";
120
+ }
121
+ };
122
+ var CMSOperationFailedError = class extends InternalServerError {
123
+ constructor(data = {}) {
124
+ const operation = data.operation || "operation";
125
+ const resource = data.resource || "resource";
126
+ super({
127
+ message: data.message || `Failed to ${operation} ${resource}`,
128
+ details: {
129
+ operation,
130
+ resource,
131
+ ...data.details
132
+ }
133
+ });
134
+ this.name = "CMSOperationFailedError";
135
+ }
136
+ };
137
+ var InsufficientCMSPermissionsError = class extends ForbiddenError {
138
+ constructor(data = {}) {
139
+ const requiredPermissions = data.requiredPermissions || [];
140
+ super({
141
+ message: data.message || `Missing required CMS permissions: ${requiredPermissions.join(", ")}`,
142
+ details: {
143
+ requiredPermissions,
144
+ resource: data.resource,
145
+ ...data.details
146
+ }
147
+ });
148
+ this.name = "InsufficientCMSPermissionsError";
149
+ }
150
+ };
151
+ export {
152
+ CMSOperationFailedError,
153
+ DuplicateLabelError,
154
+ DuplicateLabelValueError,
155
+ InsufficientCMSPermissionsError,
156
+ InvalidLabelKeyError,
157
+ InvalidLocaleError,
158
+ InvalidPublishedCacheError,
159
+ LabelNotFoundError,
160
+ LabelValueNotFoundError,
161
+ LocaleNotFoundError,
162
+ PublishedCacheNotFoundError
163
+ };
164
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/cms-errors.ts"],"sourcesContent":["/**\n * CMS Error Classes\n *\n * Custom error classes for CMS-specific scenarios\n */\n\nimport {\n ValidationError,\n NotFoundError,\n ConflictError,\n ForbiddenError,\n InternalServerError\n} from '@spfn/core/errors';\n\n/**\n * Label Not Found Error (404)\n *\n * Thrown when a CMS label does not exist\n */\nexport class LabelNotFoundError extends NotFoundError\n{\n constructor(data: { labelKey?: string; labelId?: number; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Label not found',\n details: {\n labelKey: data.labelKey,\n labelId: data.labelId,\n ...data.details\n }\n });\n this.name = 'LabelNotFoundError';\n }\n}\n\n/**\n * Label Value Not Found Error (404)\n *\n * Thrown when a CMS label value does not exist\n */\nexport class LabelValueNotFoundError extends NotFoundError\n{\n constructor(data: { labelKey?: string; locale?: string; valueId?: number; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Label value not found',\n details: {\n labelKey: data.labelKey,\n locale: data.locale,\n valueId: data.valueId,\n ...data.details\n }\n });\n this.name = 'LabelValueNotFoundError';\n }\n}\n\n/**\n * Locale Not Found Error (404)\n *\n * Thrown when requested locale does not exist in the system\n */\nexport class LocaleNotFoundError extends NotFoundError\n{\n constructor(data: { locale?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Locale not found',\n details: {\n locale: data.locale,\n ...data.details\n }\n });\n this.name = 'LocaleNotFoundError';\n }\n}\n\n/**\n * Published Cache Not Found Error (404)\n *\n * Thrown when published cache does not exist\n */\nexport class PublishedCacheNotFoundError extends NotFoundError\n{\n constructor(data: { locale?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Published cache not found',\n details: {\n locale: data.locale,\n ...data.details\n }\n });\n this.name = 'PublishedCacheNotFoundError';\n }\n}\n\n/**\n * Duplicate Label Error (409)\n *\n * Thrown when trying to create a label with existing key\n */\nexport class DuplicateLabelError extends ConflictError\n{\n constructor(data: { labelKey?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Label already exists',\n details: {\n labelKey: data.labelKey,\n ...data.details\n }\n });\n this.name = 'DuplicateLabelError';\n }\n}\n\n/**\n * Duplicate Label Value Error (409)\n *\n * Thrown when trying to create a label value that already exists\n */\nexport class DuplicateLabelValueError extends ConflictError\n{\n constructor(data: { labelKey?: string; locale?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Label value already exists for this locale',\n details: {\n labelKey: data.labelKey,\n locale: data.locale,\n ...data.details\n }\n });\n this.name = 'DuplicateLabelValueError';\n }\n}\n\n/**\n * Invalid Locale Error (400)\n *\n * Thrown when locale format is invalid or not supported\n */\nexport class InvalidLocaleError extends ValidationError\n{\n constructor(data: { locale?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Invalid locale',\n details: {\n locale: data.locale,\n ...data.details\n }\n });\n this.name = 'InvalidLocaleError';\n }\n}\n\n/**\n * Invalid Label Key Error (400)\n *\n * Thrown when label key format is invalid\n */\nexport class InvalidLabelKeyError extends ValidationError\n{\n constructor(data: { labelKey?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Invalid label key format',\n details: {\n labelKey: data.labelKey,\n ...data.details\n }\n });\n this.name = 'InvalidLabelKeyError';\n }\n}\n\n/**\n * Invalid Published Cache Error (400)\n *\n * Thrown when published cache data is malformed or corrupted\n */\nexport class InvalidPublishedCacheError extends ValidationError\n{\n constructor(data: { locale?: string; reason?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Invalid published cache data',\n details: {\n locale: data.locale,\n reason: data.reason,\n ...data.details\n }\n });\n this.name = 'InvalidPublishedCacheError';\n }\n}\n\n/**\n * CMS Operation Failed Error (500)\n *\n * Thrown when CMS operation fails unexpectedly\n */\nexport class CMSOperationFailedError extends InternalServerError\n{\n constructor(data: { operation?: string; resource?: string; message?: string; details?: Record<string, any> } = {})\n {\n const operation = data.operation || 'operation';\n const resource = data.resource || 'resource';\n super({\n message: data.message || `Failed to ${operation} ${resource}`,\n details: {\n operation,\n resource,\n ...data.details\n }\n });\n this.name = 'CMSOperationFailedError';\n }\n}\n\n/**\n * Insufficient CMS Permissions Error (403)\n *\n * Thrown when user lacks required CMS permissions\n */\nexport class InsufficientCMSPermissionsError extends ForbiddenError\n{\n constructor(data: { requiredPermissions?: string[]; resource?: string; message?: string; details?: Record<string, any> } = {})\n {\n const requiredPermissions = data.requiredPermissions || [];\n super({\n message: data.message || `Missing required CMS permissions: ${requiredPermissions.join(', ')}`,\n details: {\n requiredPermissions,\n resource: data.resource,\n ...data.details\n }\n });\n this.name = 'InsufficientCMSPermissionsError';\n }\n}"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,20 +1,138 @@
1
- import "server-only";
2
- /**
3
- * @spfn/cms
4
- *
5
- * Backend + Server Components
6
- * 백엔드 서버 컴포넌트 전용 (서버에서만 실행)
7
- *
8
- * For client components, use: import { ... } from '@spfn/cms/client'
9
- */
10
- export { getCmsConfig, configureCms, resetCmsConfig } from './cms.config.js';
11
- export type { CmsConfig } from './cms.config.js';
12
- export * from './server.js';
13
- export type { SectionData, SectionAPI } from './server.js';
14
- export * from './repositories/index.js';
15
- export * from './entities/index.js';
16
- export { syncSection, syncAll, initLabelSync, loadLabelsFromJson } from './helpers/sync.js';
17
- export * from './labels/index.js';
18
- export { createLabelSyncGenerator, LabelSyncGenerator } from './generators/label-sync-generator.js';
19
- export type * from './types.js';
20
- //# sourceMappingURL=index.d.ts.map
1
+ import * as _spfn_core_nextjs from '@spfn/core/nextjs';
2
+ import * as _spfn_core_route from '@spfn/core/route';
3
+ import * as _sinclair_typebox from '@sinclair/typebox';
4
+
5
+ /**
6
+ * Bind locale to labels, returning locale-specific values
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const labelsDefinition = defineLabels({
11
+ * home: {
12
+ * title: { en: "Home", ko: "홈" }
13
+ * }
14
+ * });
15
+ *
16
+ * const labels = bindLocale(labelsDefinition, 'ko');
17
+ * labels.home.title // "홈"
18
+ * ```
19
+ */
20
+ /**
21
+ * Type that converts locale records to strings
22
+ */
23
+ type BoundLabels<T> = {
24
+ [K in keyof T]: T[K] extends Record<string, any> ? IsLocaleRecord<T[K]> extends true ? string : BoundLabels<T[K]> : T[K];
25
+ };
26
+ /**
27
+ * Extract section keys from label definition
28
+ */
29
+ type SectionKeys<T> = Extract<keyof T, string>;
30
+ /**
31
+ * Get content of a single section (without section name wrapper)
32
+ */
33
+ type BoundLabelSection<T, K extends SectionKeys<T>> = BoundLabels<T>[K];
34
+ /**
35
+ * Pick specific sections from bound labels (for multiple sections)
36
+ */
37
+ type BoundLabelsSections<T, K extends SectionKeys<T>> = Pick<BoundLabels<T>, K>;
38
+ /**
39
+ * Check if object is a locale record (has string values only)
40
+ */
41
+ type IsLocaleRecord<T> = T extends Record<string, string> ? true : false;
42
+
43
+ /**
44
+ * Defines a type-safe label configuration.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * export const labelConfig = defineLabelConfig({
49
+ * locales: ['en', 'ar'] as const,
50
+ * defaultLocale: 'en',
51
+ * fallbackLocale: 'en', // Optional
52
+ * });
53
+ *
54
+ * export type LabelConfig = typeof labelConfig;
55
+ * export type AppLocale = typeof labelConfig.locales[number]; // 'en' | 'ar'
56
+ * ```
57
+ */
58
+ declare function defineLabelConfig<const TLocales extends readonly string[]>(config: {
59
+ locales: TLocales;
60
+ defaultLocale: TLocales[number];
61
+ fallbackLocale?: TLocales[number];
62
+ useBrowserLanguage?: boolean;
63
+ }): {
64
+ locales: TLocales;
65
+ defaultLocale: TLocales[number];
66
+ fallbackLocale?: TLocales[number];
67
+ useBrowserLanguage?: boolean;
68
+ };
69
+ /**
70
+ * Define nested label structure (tRPC-style)
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * export const labels = defineLabels({
75
+ * home: {
76
+ * slogan: { en: "Welcome", ko: "환영합니다" },
77
+ * hero: {
78
+ * title: { en: "Hello", ko: "안녕하세요" }
79
+ * }
80
+ * },
81
+ * about: {
82
+ * title: { en: "About Us", ko: "회사 소개" }
83
+ * }
84
+ * });
85
+ *
86
+ * // Usage
87
+ * labels.home.slogan;
88
+ * labels.home.hero.title;
89
+ * labels.about.title;
90
+ * ```
91
+ */
92
+ declare function defineLabels<const T>(labels: T): T;
93
+ declare function format(template: string, vars: Record<string, string | number>): string;
94
+
95
+ /**
96
+ * Create CMS client with API, label getters, and format utility
97
+ *
98
+ * @param labelsDefinition - Labels defined using defineLabels()
99
+ * @param config - Label config from defineLabelConfig()
100
+ * @returns API client, getLabel (single), getLabels (multiple), and format utility
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * // labels.ts - Setup once
105
+ * export const { api, getLabel, getLabels, format } = createCmsClient(labelsDefinition, labelConfig);
106
+ *
107
+ * // Single section - direct access
108
+ * const label = await getLabel('home');
109
+ * label.hero.title // "Hello" (no section name!)
110
+ *
111
+ * // Multiple sections - with section names
112
+ * const labels = await getLabels(['home', 'about']);
113
+ * labels.home.hero.title // "Hello"
114
+ * labels.about.title // "About Us"
115
+ *
116
+ * // With template variables
117
+ * const greeting = label.hero.greeting; // "Hello {name}"
118
+ * format(greeting, { name: "John" }); // "Hello John"
119
+ * ```
120
+ */
121
+ declare function createCmsClient<T>(labelsDefinition: T, config: {
122
+ defaultLocale: string;
123
+ fallbackLocale?: string;
124
+ }): {
125
+ api: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
126
+ getLabelCache: _spfn_core_route.RouteDef<{
127
+ query: _sinclair_typebox.TObject<{
128
+ sections: _sinclair_typebox.TArray<_sinclair_typebox.TString>;
129
+ locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
130
+ }>;
131
+ }, {}, Record<string, any>>;
132
+ }>>;
133
+ getLabel: <K extends SectionKeys<T>>(section: K) => Promise<BoundLabelSection<T, K>>;
134
+ getLabels: <K extends SectionKeys<T>>(sections: readonly K[]) => Promise<BoundLabelsSections<T, K>>;
135
+ format: typeof format;
136
+ };
137
+
138
+ export { type BoundLabelSection, type BoundLabels, type BoundLabelsSections, type SectionKeys, createCmsClient, defineLabelConfig, defineLabels, format };