@spfn/cms 0.1.0-alpha.7 → 0.1.0-alpha.71
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.
- package/README.md +28 -416
- package/dist/{helpers/locale.actions.d.ts → actions-BpTAYuBA.d.ts} +70 -7
- package/dist/actions.d.ts +2 -9
- package/dist/actions.js +97 -10
- package/dist/actions.js.map +1 -1
- package/dist/api.d.ts +214 -0
- package/dist/api.js +353 -0
- package/dist/api.js.map +1 -0
- package/dist/client.d.ts +136 -127
- package/dist/client.js +1199 -59
- package/dist/client.js.map +1 -1
- package/dist/{types.d.ts → index-Dh5FjWzR.d.ts} +45 -7
- package/dist/index.d.ts +108 -16
- package/dist/index.js +610 -23
- package/dist/index.js.map +1 -1
- package/dist/label-sync-generator-B0EmvtWM.d.ts +32 -0
- package/dist/lib/contracts/labels.d.ts +151 -0
- package/dist/lib/contracts/labels.js +168 -0
- package/dist/lib/contracts/labels.js.map +1 -0
- package/dist/lib/contracts/published-cache.d.ts +48 -0
- package/dist/lib/contracts/published-cache.js +49 -0
- package/dist/lib/contracts/published-cache.js.map +1 -0
- package/dist/lib/contracts/values.d.ts +71 -0
- package/dist/lib/contracts/values.js +103 -0
- package/dist/lib/contracts/values.js.map +1 -0
- package/dist/locale.constants-BMBK70YM.d.ts +104 -0
- package/dist/{entities → server/entities}/cms-audit-logs.d.ts +15 -70
- package/dist/server/entities/cms-audit-logs.js +78 -0
- package/dist/server/entities/cms-audit-logs.js.map +1 -0
- package/dist/{entities → server/entities}/cms-draft-cache.d.ts +13 -73
- package/dist/server/entities/cms-draft-cache.js +38 -0
- package/dist/server/entities/cms-draft-cache.js.map +1 -0
- package/dist/{entities → server/entities}/cms-label-values.d.ts +16 -67
- package/dist/server/entities/cms-label-values.js +81 -0
- package/dist/server/entities/cms-label-values.js.map +1 -0
- package/dist/{entities → server/entities}/cms-label-versions.d.ts +16 -49
- package/dist/server/entities/cms-label-versions.js +76 -0
- package/dist/server/entities/cms-label-versions.js.map +1 -0
- package/dist/{entities → server/entities}/cms-labels.d.ts +17 -14
- package/dist/server/entities/cms-labels.js +42 -0
- package/dist/server/entities/cms-labels.js.map +1 -0
- package/dist/{entities → server/entities}/cms-published-cache.d.ts +14 -69
- package/dist/server/entities/cms-published-cache.js +36 -0
- package/dist/server/entities/cms-published-cache.js.map +1 -0
- package/dist/server/entities/index.d.ts +7 -0
- package/dist/server/entities/index.js +218 -0
- package/dist/server/entities/index.js.map +1 -0
- package/dist/server/generators/index.d.ts +19 -0
- package/dist/server/generators/index.js +753 -0
- package/dist/server/generators/index.js.map +1 -0
- package/dist/server/labels/index.d.ts +1 -0
- package/dist/server/labels/index.js +32 -0
- package/dist/server/labels/index.js.map +1 -0
- package/dist/server/repositories/index.d.ts +209 -0
- package/dist/server/repositories/index.js +441 -0
- package/dist/server/repositories/index.js.map +1 -0
- package/dist/server/routes/labels/[id]/index.js +508 -0
- package/dist/server/routes/labels/[id]/index.js.map +1 -0
- package/dist/{routes/labels/[id] → server/routes/labels/_id_}/index.d.ts +5 -3
- package/dist/server/routes/labels/by-key/[key]/index.js +458 -0
- package/dist/server/routes/labels/by-key/[key]/index.js.map +1 -0
- package/dist/server/routes/labels/by-key/_key_/index.d.ts +10 -0
- package/dist/server/routes/labels/index.d.ts +12 -0
- package/dist/server/routes/labels/index.js +620 -0
- package/dist/server/routes/labels/index.js.map +1 -0
- package/dist/server/routes/published-cache/index.d.ts +11 -0
- package/dist/server/routes/published-cache/index.js +369 -0
- package/dist/server/routes/published-cache/index.js.map +1 -0
- package/dist/server/routes/values/[labelId]/[version]/index.js +479 -0
- package/dist/server/routes/values/[labelId]/[version]/index.js.map +1 -0
- package/dist/server/routes/values/[labelId]/index.js +474 -0
- package/dist/server/routes/values/[labelId]/index.js.map +1 -0
- package/dist/server/routes/values/_labelId_/_version_/index.d.ts +10 -0
- package/dist/server/routes/values/_labelId_/index.d.ts +10 -0
- package/dist/server.d.ts +78 -7
- package/dist/server.js +1750 -247
- package/dist/server.js.map +1 -1
- package/migrations/0000_init.sql +3 -0
- package/migrations/0001_far_lady_vermin.sql +86 -0
- package/migrations/0002_heavy_the_enforcers.sql +2 -0
- package/migrations/meta/0000_snapshot.json +15 -0
- package/migrations/meta/0001_snapshot.json +687 -0
- package/migrations/meta/0002_snapshot.json +686 -0
- package/migrations/meta/_journal.json +27 -0
- package/package.json +55 -36
- package/dist/actions.d.ts.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/cms.config.d.ts +0 -77
- package/dist/cms.config.d.ts.map +0 -1
- package/dist/cms.config.js +0 -111
- package/dist/cms.config.js.map +0 -1
- package/dist/entities/cms-audit-logs.d.ts.map +0 -1
- package/dist/entities/cms-audit-logs.js +0 -103
- package/dist/entities/cms-audit-logs.js.map +0 -1
- package/dist/entities/cms-draft-cache.d.ts.map +0 -1
- package/dist/entities/cms-draft-cache.js +0 -112
- package/dist/entities/cms-draft-cache.js.map +0 -1
- package/dist/entities/cms-label-values.d.ts.map +0 -1
- package/dist/entities/cms-label-values.js +0 -105
- package/dist/entities/cms-label-values.js.map +0 -1
- package/dist/entities/cms-label-versions.d.ts.map +0 -1
- package/dist/entities/cms-label-versions.js +0 -80
- package/dist/entities/cms-label-versions.js.map +0 -1
- package/dist/entities/cms-labels.d.ts.map +0 -1
- package/dist/entities/cms-labels.js +0 -48
- package/dist/entities/cms-labels.js.map +0 -1
- package/dist/entities/cms-published-cache.d.ts.map +0 -1
- package/dist/entities/cms-published-cache.js +0 -103
- package/dist/entities/cms-published-cache.js.map +0 -1
- package/dist/entities/index.d.ts +0 -10
- package/dist/entities/index.d.ts.map +0 -1
- package/dist/entities/index.js +0 -10
- package/dist/entities/index.js.map +0 -1
- package/dist/generators/index.d.ts +0 -19
- package/dist/generators/index.d.ts.map +0 -1
- package/dist/generators/index.js +0 -19
- package/dist/generators/index.js.map +0 -1
- package/dist/generators/label-sync-generator.d.ts +0 -33
- package/dist/generators/label-sync-generator.d.ts.map +0 -1
- package/dist/generators/label-sync-generator.js +0 -87
- package/dist/generators/label-sync-generator.js.map +0 -1
- package/dist/helpers/locale.actions.d.ts.map +0 -1
- package/dist/helpers/locale.actions.js +0 -210
- package/dist/helpers/locale.actions.js.map +0 -1
- package/dist/helpers/locale.constants.d.ts +0 -10
- package/dist/helpers/locale.constants.d.ts.map +0 -1
- package/dist/helpers/locale.constants.js +0 -10
- package/dist/helpers/locale.constants.js.map +0 -1
- package/dist/helpers/locale.d.ts +0 -17
- package/dist/helpers/locale.d.ts.map +0 -1
- package/dist/helpers/locale.js +0 -20
- package/dist/helpers/locale.js.map +0 -1
- package/dist/helpers/sync.d.ts +0 -41
- package/dist/helpers/sync.d.ts.map +0 -1
- package/dist/helpers/sync.js +0 -309
- package/dist/helpers/sync.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/init.d.ts +0 -31
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -36
- package/dist/init.js.map +0 -1
- package/dist/labels/helpers.d.ts +0 -31
- package/dist/labels/helpers.d.ts.map +0 -1
- package/dist/labels/helpers.js +0 -60
- package/dist/labels/helpers.js.map +0 -1
- package/dist/labels/index.d.ts +0 -7
- package/dist/labels/index.d.ts.map +0 -1
- package/dist/labels/index.js +0 -7
- package/dist/labels/index.js.map +0 -1
- package/dist/repositories/cms-draft-cache.repository.d.ts +0 -62
- package/dist/repositories/cms-draft-cache.repository.d.ts.map +0 -1
- package/dist/repositories/cms-draft-cache.repository.js +0 -56
- package/dist/repositories/cms-draft-cache.repository.js.map +0 -1
- package/dist/repositories/cms-label-values.repository.d.ts +0 -32
- package/dist/repositories/cms-label-values.repository.d.ts.map +0 -1
- package/dist/repositories/cms-label-values.repository.js +0 -72
- package/dist/repositories/cms-label-values.repository.js.map +0 -1
- package/dist/repositories/cms-labels.repository.d.ts +0 -53
- package/dist/repositories/cms-labels.repository.d.ts.map +0 -1
- package/dist/repositories/cms-labels.repository.js +0 -77
- package/dist/repositories/cms-labels.repository.js.map +0 -1
- package/dist/repositories/cms-published-cache.repository.d.ts +0 -53
- package/dist/repositories/cms-published-cache.repository.d.ts.map +0 -1
- package/dist/repositories/cms-published-cache.repository.js +0 -54
- package/dist/repositories/cms-published-cache.repository.js.map +0 -1
- package/dist/repositories/index.d.ts +0 -8
- package/dist/repositories/index.d.ts.map +0 -1
- package/dist/repositories/index.js +0 -9
- package/dist/repositories/index.js.map +0 -1
- package/dist/routes/labels/[id]/contract.d.ts +0 -68
- package/dist/routes/labels/[id]/contract.d.ts.map +0 -1
- package/dist/routes/labels/[id]/contract.js +0 -84
- package/dist/routes/labels/[id]/contract.js.map +0 -1
- package/dist/routes/labels/[id]/index.d.ts.map +0 -1
- package/dist/routes/labels/[id]/index.js +0 -96
- package/dist/routes/labels/[id]/index.js.map +0 -1
- package/dist/routes/labels/by-key/[key]/contract.d.ts +0 -24
- package/dist/routes/labels/by-key/[key]/contract.d.ts.map +0 -1
- package/dist/routes/labels/by-key/[key]/contract.js +0 -28
- package/dist/routes/labels/by-key/[key]/contract.js.map +0 -1
- package/dist/routes/labels/by-key/[key]/index.d.ts +0 -8
- package/dist/routes/labels/by-key/[key]/index.d.ts.map +0 -1
- package/dist/routes/labels/by-key/[key]/index.js +0 -32
- package/dist/routes/labels/by-key/[key]/index.js.map +0 -1
- package/dist/routes/labels/contract.d.ts +0 -59
- package/dist/routes/labels/contract.d.ts.map +0 -1
- package/dist/routes/labels/contract.js +0 -75
- package/dist/routes/labels/contract.js.map +0 -1
- package/dist/routes/labels/index.d.ts +0 -10
- package/dist/routes/labels/index.d.ts.map +0 -1
- package/dist/routes/labels/index.js +0 -73
- package/dist/routes/labels/index.js.map +0 -1
- package/dist/routes/published-cache/contract.d.ts +0 -25
- package/dist/routes/published-cache/contract.d.ts.map +0 -1
- package/dist/routes/published-cache/contract.js +0 -35
- package/dist/routes/published-cache/contract.js.map +0 -1
- package/dist/routes/published-cache/index.d.ts +0 -8
- package/dist/routes/published-cache/index.d.ts.map +0 -1
- package/dist/routes/published-cache/index.js +0 -33
- package/dist/routes/published-cache/index.js.map +0 -1
- package/dist/routes/values/[labelId]/[version]/contract.d.ts +0 -29
- package/dist/routes/values/[labelId]/[version]/contract.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/[version]/contract.js +0 -33
- package/dist/routes/values/[labelId]/[version]/contract.js.map +0 -1
- package/dist/routes/values/[labelId]/[version]/index.d.ts +0 -8
- package/dist/routes/values/[labelId]/[version]/index.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/[version]/index.js +0 -45
- package/dist/routes/values/[labelId]/[version]/index.js.map +0 -1
- package/dist/routes/values/[labelId]/contract.d.ts +0 -38
- package/dist/routes/values/[labelId]/contract.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/contract.js +0 -59
- package/dist/routes/values/[labelId]/contract.js.map +0 -1
- package/dist/routes/values/[labelId]/index.d.ts +0 -8
- package/dist/routes/values/[labelId]/index.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/index.js +0 -42
- package/dist/routes/values/[labelId]/index.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/store.d.ts +0 -87
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -205
- package/dist/store.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -7
- package/dist/types.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB;;;;;;;GAOG;AAEH,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG7E,kDAAkD;AAClD,cAAc,UAAU,CAAC;AAGzB,oCAAoC;AACpC,cAAc,gBAAgB,CAAC;AAE/B,iCAAiC;AACjC,cAAc,YAAY,CAAC;AAE3B,wDAAwD;AACxD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzF,sDAAsD;AACtD,cAAc,UAAU,CAAC;AAEzB,gDAAgD;AAChD,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"sources":["../src/server/config/cms.config.ts","../src/lib/constants/index.ts","../src/lib/constants/locale.constants.ts"],"sourcesContent":["/**\n * CMS Configuration Module\n *\n * 환경변수 기반 CMS 설정 관리\n * - SPFN_CMS_DEFAULT_LOCALE: 기본 언어 (기본값: 'ko')\n * - SPFN_CMS_SUPPORTED_LOCALES: 지원 언어 목록, 쉼표로 구분 (기본값: 'ko,en')\n * - SPFN_CMS_DETECT_BROWSER_LANGUAGE: 브라우저 언어 자동 감지 (기본값: 'false')\n */\n\n/**\n * CMS 설정 타입\n */\nexport interface CmsConfig\n{\n /**\n * 기본 언어 코드\n * @example 'ko', 'en', 'ja'\n */\n defaultLocale: string;\n\n /**\n * 지원하는 언어 목록\n * @example ['ko', 'en', 'ja']\n */\n supportedLocales: string[];\n\n /**\n * 브라우저 언어 자동 감지 여부\n * @default true\n */\n detectBrowserLanguage: boolean;\n}\n\n/**\n * 환경변수 읽기 헬퍼\n */\nfunction getEnvVar(key: string, defaultValue: string): string\n{\n return process.env[key] || defaultValue;\n}\n\n/**\n * 환경변수에서 boolean 읽기\n */\nfunction getEnvBoolean(key: string, defaultValue: boolean): boolean\n{\n const value = process.env[key];\n if (value === undefined) return defaultValue;\n return value === 'true' || value === '1';\n}\n\n/**\n * 환경변수에서 설정 로드\n */\nfunction loadConfigFromEnv(): CmsConfig\n{\n const defaultLocale = getEnvVar('SPFN_CMS_DEFAULT_LOCALE', 'en');\n const supportedLocalesStr = getEnvVar('SPFN_CMS_SUPPORTED_LOCALES', 'en,ko');\n const detectBrowserLanguage = getEnvBoolean('SPFN_CMS_DETECT_BROWSER_LANGUAGE', true);\n\n const supportedLocales = supportedLocalesStr\n .split(',')\n .map(locale => locale.trim())\n .filter(locale => locale.length > 0);\n\n // 기본 언어가 지원 목록에 없으면 추가\n if (!supportedLocales.includes(defaultLocale))\n {\n supportedLocales.unshift(defaultLocale);\n }\n\n return {\n defaultLocale,\n supportedLocales,\n detectBrowserLanguage,\n };\n}\n\n/**\n * 현재 설정 (환경변수에서 초기화)\n */\nlet currentConfig: CmsConfig = loadConfigFromEnv();\n\n/**\n * CMS 설정 조회\n *\n * @returns 현재 CMS 설정\n *\n * @example\n * ```tsx\n * import { getCmsConfig } from '@spfn/cms';\n *\n * const config = getCmsConfig();\n * console.log(config.defaultLocale); // 'ko'\n * console.log(config.supportedLocales); // ['ko', 'en']\n * ```\n */\nexport function getCmsConfig(): Readonly<CmsConfig>\n{\n return currentConfig;\n}\n\n/**\n * CMS 설정 변경 (런타임 오버라이드)\n *\n * 환경변수 설정을 런타임에 오버라이드합니다.\n * 주로 테스트나 특수한 경우에 사용됩니다.\n *\n * @param config - 변경할 설정 (부분 업데이트 가능)\n *\n * @example\n * ```tsx\n * import { configureCms } from '@spfn/cms';\n *\n * // 앱 초기화 시 (선택적)\n * configureCms({\n * defaultLocale: 'en',\n * supportedLocales: ['en', 'ko', 'ja'],\n * detectBrowserLanguage: true,\n * });\n * ```\n */\nexport function configureCms(config: Partial<CmsConfig>): void\n{\n currentConfig = {\n ...currentConfig,\n ...config,\n };\n\n // 기본 언어가 지원 목록에 있는지 확인\n if (config.defaultLocale && !currentConfig.supportedLocales.includes(config.defaultLocale))\n {\n console.warn(\n `[CMS Config] Default locale '${config.defaultLocale}' not in supported locales, adding automatically.`,\n `Supported locales: [${currentConfig.supportedLocales.join(', ')}]`\n );\n\n currentConfig.supportedLocales.unshift(config.defaultLocale);\n }\n}\n\n/**\n * 설정 초기화 (환경변수에서 재로드)\n *\n * @example\n * ```tsx\n * import { resetCmsConfig } from '@spfn/cms';\n *\n * // 환경변수 설정으로 되돌리기\n * resetCmsConfig();\n * ```\n */\nexport function resetCmsConfig(): void\n{\n currentConfig = loadConfigFromEnv();\n}","/**\n * CMS Constants\n *\n * CMS 패키지에서 사용하는 전역 상수\n */\n\n/**\n * 기본 라벨 디렉토리 경로\n *\n * JSON 라벨 파일이 저장되는 기본 디렉토리입니다.\n * 프로젝트 루트 기준 상대 경로입니다.\n *\n * @example\n * ```typescript\n * import { DEFAULT_LABELS_DIR } from '@spfn/cms';\n *\n * console.log(DEFAULT_LABELS_DIR); // 'src/lib/labels'\n * ```\n */\nexport const DEFAULT_LABELS_DIR = 'src/lib/labels';","/**\n * Locale Constants\n *\n * Server/Client 양쪽에서 사용 가능한 locale 관련 상수\n */\n\n/**\n * Locale 쿠키 키\n */\nexport const LOCALE_COOKIE_KEY = 'spfn-locale';\n\n/**\n * 지원하는 Locale 타입 (Type-safe)\n */\nexport type SupportedLocale =\n // 아시아-태평양\n | 'ko' // 한국어\n | 'ja' // 일본어\n | 'zh' // 중국어 (간체)\n | 'zh-TW' // 중국어 (번체, 대만)\n | 'zh-HK' // 중국어 (홍콩)\n | 'hi' // 힌디어\n | 'th' // 태국어\n | 'vi' // 베트남어\n | 'id' // 인도네시아어\n | 'ms' // 말레이어\n // 영어권\n | 'en' // 영어 (미국)\n | 'en-GB' // 영어 (영국)\n | 'en-CA' // 영어 (캐나다)\n | 'en-AU' // 영어 (호주)\n | 'en-NZ' // 영어 (뉴질랜드)\n // 서유럽\n | 'es' // 스페인어 (스페인)\n | 'es-MX' // 스페인어 (멕시코)\n | 'es-AR' // 스페인어 (아르헨티나)\n | 'es-CO' // 스페인어 (콜롬비아)\n | 'fr' // 프랑스어\n | 'de' // 독일어\n | 'it' // 이탈리아어\n | 'pt' // 포르투갈어\n | 'nl' // 네덜란드어\n // 북유럽\n | 'sv' // 스웨덴어\n | 'no' // 노르웨이어\n | 'da' // 덴마크어\n | 'fi' // 핀란드어\n // 동유럽\n | 'ru' // 러시아어\n | 'pl' // 폴란드어\n | 'uk' // 우크라이나어\n | 'cs' // 체코어\n | 'hu' // 헝가리어\n | 'ro' // 루마니아어\n | 'bg' // 불가리아어\n | 'hr' // 크로아티아어\n | 'sr' // 세르비아어\n | 'sk' // 슬로바키아어\n | 'sl' // 슬로베니아어\n | 'lt' // 리투아니아어\n | 'lv' // 라트비아어\n | 'et' // 에스토니아어\n // 남유럽\n | 'el' // 그리스어\n // 중동\n | 'tr' // 터키어\n | 'ar' // 아랍어\n | 'fa' // 페르시아어\n | 'he' // 히브리어\n // 아프리카\n | 'sw'; // 스와힐리어\n\n/**\n * 국가/지역 정보 타입\n */\nexport interface LocaleInfo\n{\n /** Locale 코드 (ISO 639-1) */\n locale: SupportedLocale;\n /** 국가 코드 (ISO 3166-1 alpha-2) */\n countryCode: string;\n /** 국기 이모지 (HTML/React용) */\n flag: string;\n /** 전화번호 국가 코드 */\n dialCode: string;\n /** 네이티브 이름 (현지어) */\n nativeName: string;\n /** 영어 이름 */\n englishName: string;\n /** RTL (Right-to-Left) 여부 */\n rtl?: boolean;\n /** 통화 코드 (ISO 4217) */\n currencyCode?: string;\n /** 날짜 형식 예시 */\n dateFormat?: string;\n}\n\n/**\n * 사전 정의된 Locale 정보 맵\n *\n * 주요 언어/국가 정보를 포함합니다.\n * 프로젝트에 맞게 추가/수정 가능합니다.\n */\nexport const LOCALE_INFO_MAP: Record<SupportedLocale, LocaleInfo> = {\n // 한국어\n ko: {\n locale: 'ko',\n countryCode: 'KR',\n flag: '🇰🇷',\n dialCode: '+82',\n nativeName: '한국어',\n englishName: 'Korean',\n currencyCode: 'KRW',\n dateFormat: 'YYYY.MM.DD',\n },\n\n // 영어 (미국)\n en: {\n locale: 'en',\n countryCode: 'US',\n flag: '🇺🇸',\n dialCode: '+1',\n nativeName: 'English',\n englishName: 'English',\n currencyCode: 'USD',\n dateFormat: 'MM/DD/YYYY',\n },\n\n // 일본어\n ja: {\n locale: 'ja',\n countryCode: 'JP',\n flag: '🇯🇵',\n dialCode: '+81',\n nativeName: '日本語',\n englishName: 'Japanese',\n currencyCode: 'JPY',\n dateFormat: 'YYYY/MM/DD',\n },\n\n // 중국어 (간체)\n zh: {\n locale: 'zh',\n countryCode: 'CN',\n flag: '🇨🇳',\n dialCode: '+86',\n nativeName: '简体中文',\n englishName: 'Chinese (Simplified)',\n currencyCode: 'CNY',\n dateFormat: 'YYYY-MM-DD',\n },\n\n // 중국어 (번체, 대만)\n 'zh-TW': {\n locale: 'zh-TW',\n countryCode: 'TW',\n flag: '🇹🇼',\n dialCode: '+886',\n nativeName: '繁體中文',\n englishName: 'Chinese (Traditional)',\n currencyCode: 'TWD',\n dateFormat: 'YYYY/MM/DD',\n },\n\n // 스페인어\n es: {\n locale: 'es',\n countryCode: 'ES',\n flag: '🇪🇸',\n dialCode: '+34',\n nativeName: 'Español',\n englishName: 'Spanish',\n currencyCode: 'EUR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 프랑스어\n fr: {\n locale: 'fr',\n countryCode: 'FR',\n flag: '🇫🇷',\n dialCode: '+33',\n nativeName: 'Français',\n englishName: 'French',\n currencyCode: 'EUR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 독일어\n de: {\n locale: 'de',\n countryCode: 'DE',\n flag: '🇩🇪',\n dialCode: '+49',\n nativeName: 'Deutsch',\n englishName: 'German',\n currencyCode: 'EUR',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 이탈리아어\n it: {\n locale: 'it',\n countryCode: 'IT',\n flag: '🇮🇹',\n dialCode: '+39',\n nativeName: 'Italiano',\n englishName: 'Italian',\n currencyCode: 'EUR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 포르투갈어 (브라질)\n pt: {\n locale: 'pt',\n countryCode: 'BR',\n flag: '🇧🇷',\n dialCode: '+55',\n nativeName: 'Português',\n englishName: 'Portuguese',\n currencyCode: 'BRL',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 러시아어\n ru: {\n locale: 'ru',\n countryCode: 'RU',\n flag: '🇷🇺',\n dialCode: '+7',\n nativeName: 'Русский',\n englishName: 'Russian',\n currencyCode: 'RUB',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 아랍어\n ar: {\n locale: 'ar',\n countryCode: 'SA',\n flag: '🇸🇦',\n dialCode: '+966',\n nativeName: 'العربية',\n englishName: 'Arabic',\n rtl: true,\n currencyCode: 'SAR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 힌디어\n hi: {\n locale: 'hi',\n countryCode: 'IN',\n flag: '🇮🇳',\n dialCode: '+91',\n nativeName: 'हिन्दी',\n englishName: 'Hindi',\n currencyCode: 'INR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 태국어\n th: {\n locale: 'th',\n countryCode: 'TH',\n flag: '🇹🇭',\n dialCode: '+66',\n nativeName: 'ไทย',\n englishName: 'Thai',\n currencyCode: 'THB',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 베트남어\n vi: {\n locale: 'vi',\n countryCode: 'VN',\n flag: '🇻🇳',\n dialCode: '+84',\n nativeName: 'Tiếng Việt',\n englishName: 'Vietnamese',\n currencyCode: 'VND',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 인도네시아어\n id: {\n locale: 'id',\n countryCode: 'ID',\n flag: '🇮🇩',\n dialCode: '+62',\n nativeName: 'Bahasa Indonesia',\n englishName: 'Indonesian',\n currencyCode: 'IDR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 터키어\n tr: {\n locale: 'tr',\n countryCode: 'TR',\n flag: '🇹🇷',\n dialCode: '+90',\n nativeName: 'Türkçe',\n englishName: 'Turkish',\n currencyCode: 'TRY',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 폴란드어\n pl: {\n locale: 'pl',\n countryCode: 'PL',\n flag: '🇵🇱',\n dialCode: '+48',\n nativeName: 'Polski',\n englishName: 'Polish',\n currencyCode: 'PLN',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 네덜란드어\n nl: {\n locale: 'nl',\n countryCode: 'NL',\n flag: '🇳🇱',\n dialCode: '+31',\n nativeName: 'Nederlands',\n englishName: 'Dutch',\n currencyCode: 'EUR',\n dateFormat: 'DD-MM-YYYY',\n },\n\n // 중국어 (홍콩)\n 'zh-HK': {\n locale: 'zh-HK',\n countryCode: 'HK',\n flag: '🇭🇰',\n dialCode: '+852',\n nativeName: '繁體中文 (香港)',\n englishName: 'Chinese (Hong Kong)',\n currencyCode: 'HKD',\n dateFormat: 'YYYY/MM/DD',\n },\n\n // 말레이어\n ms: {\n locale: 'ms',\n countryCode: 'MY',\n flag: '🇲🇾',\n dialCode: '+60',\n nativeName: 'Bahasa Melayu',\n englishName: 'Malay',\n currencyCode: 'MYR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 영어 (영국)\n 'en-GB': {\n locale: 'en-GB',\n countryCode: 'GB',\n flag: '🇬🇧',\n dialCode: '+44',\n nativeName: 'English (UK)',\n englishName: 'English (United Kingdom)',\n currencyCode: 'GBP',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 영어 (캐나다)\n 'en-CA': {\n locale: 'en-CA',\n countryCode: 'CA',\n flag: '🇨🇦',\n dialCode: '+1',\n nativeName: 'English (Canada)',\n englishName: 'English (Canada)',\n currencyCode: 'CAD',\n dateFormat: 'YYYY-MM-DD',\n },\n\n // 영어 (호주)\n 'en-AU': {\n locale: 'en-AU',\n countryCode: 'AU',\n flag: '🇦🇺',\n dialCode: '+61',\n nativeName: 'English (Australia)',\n englishName: 'English (Australia)',\n currencyCode: 'AUD',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 영어 (뉴질랜드)\n 'en-NZ': {\n locale: 'en-NZ',\n countryCode: 'NZ',\n flag: '🇳🇿',\n dialCode: '+64',\n nativeName: 'English (New Zealand)',\n englishName: 'English (New Zealand)',\n currencyCode: 'NZD',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 스페인어 (멕시코)\n 'es-MX': {\n locale: 'es-MX',\n countryCode: 'MX',\n flag: '🇲🇽',\n dialCode: '+52',\n nativeName: 'Español (México)',\n englishName: 'Spanish (Mexico)',\n currencyCode: 'MXN',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 스페인어 (아르헨티나)\n 'es-AR': {\n locale: 'es-AR',\n countryCode: 'AR',\n flag: '🇦🇷',\n dialCode: '+54',\n nativeName: 'Español (Argentina)',\n englishName: 'Spanish (Argentina)',\n currencyCode: 'ARS',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 스페인어 (콜롬비아)\n 'es-CO': {\n locale: 'es-CO',\n countryCode: 'CO',\n flag: '🇨🇴',\n dialCode: '+57',\n nativeName: 'Español (Colombia)',\n englishName: 'Spanish (Colombia)',\n currencyCode: 'COP',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 스웨덴어\n sv: {\n locale: 'sv',\n countryCode: 'SE',\n flag: '🇸🇪',\n dialCode: '+46',\n nativeName: 'Svenska',\n englishName: 'Swedish',\n currencyCode: 'SEK',\n dateFormat: 'YYYY-MM-DD',\n },\n\n // 노르웨이어\n no: {\n locale: 'no',\n countryCode: 'NO',\n flag: '🇳🇴',\n dialCode: '+47',\n nativeName: 'Norsk',\n englishName: 'Norwegian',\n currencyCode: 'NOK',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 덴마크어\n da: {\n locale: 'da',\n countryCode: 'DK',\n flag: '🇩🇰',\n dialCode: '+45',\n nativeName: 'Dansk',\n englishName: 'Danish',\n currencyCode: 'DKK',\n dateFormat: 'DD-MM-YYYY',\n },\n\n // 핀란드어\n fi: {\n locale: 'fi',\n countryCode: 'FI',\n flag: '🇫🇮',\n dialCode: '+358',\n nativeName: 'Suomi',\n englishName: 'Finnish',\n currencyCode: 'EUR',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 우크라이나어\n uk: {\n locale: 'uk',\n countryCode: 'UA',\n flag: '🇺🇦',\n dialCode: '+380',\n nativeName: 'Українська',\n englishName: 'Ukrainian',\n currencyCode: 'UAH',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 체코어\n cs: {\n locale: 'cs',\n countryCode: 'CZ',\n flag: '🇨🇿',\n dialCode: '+420',\n nativeName: 'Čeština',\n englishName: 'Czech',\n currencyCode: 'CZK',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 헝가리어\n hu: {\n locale: 'hu',\n countryCode: 'HU',\n flag: '🇭🇺',\n dialCode: '+36',\n nativeName: 'Magyar',\n englishName: 'Hungarian',\n currencyCode: 'HUF',\n dateFormat: 'YYYY.MM.DD.',\n },\n\n // 루마니아어\n ro: {\n locale: 'ro',\n countryCode: 'RO',\n flag: '🇷🇴',\n dialCode: '+40',\n nativeName: 'Română',\n englishName: 'Romanian',\n currencyCode: 'RON',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 불가리아어\n bg: {\n locale: 'bg',\n countryCode: 'BG',\n flag: '🇧🇬',\n dialCode: '+359',\n nativeName: 'Български',\n englishName: 'Bulgarian',\n currencyCode: 'BGN',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 크로아티아어\n hr: {\n locale: 'hr',\n countryCode: 'HR',\n flag: '🇭🇷',\n dialCode: '+385',\n nativeName: 'Hrvatski',\n englishName: 'Croatian',\n currencyCode: 'HRK',\n dateFormat: 'DD.MM.YYYY.',\n },\n\n // 세르비아어\n sr: {\n locale: 'sr',\n countryCode: 'RS',\n flag: '🇷🇸',\n dialCode: '+381',\n nativeName: 'Српски',\n englishName: 'Serbian',\n currencyCode: 'RSD',\n dateFormat: 'DD.MM.YYYY.',\n },\n\n // 슬로바키아어\n sk: {\n locale: 'sk',\n countryCode: 'SK',\n flag: '🇸🇰',\n dialCode: '+421',\n nativeName: 'Slovenčina',\n englishName: 'Slovak',\n currencyCode: 'EUR',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 슬로베니아어\n sl: {\n locale: 'sl',\n countryCode: 'SI',\n flag: '🇸🇮',\n dialCode: '+386',\n nativeName: 'Slovenščina',\n englishName: 'Slovenian',\n currencyCode: 'EUR',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 리투아니아어\n lt: {\n locale: 'lt',\n countryCode: 'LT',\n flag: '🇱🇹',\n dialCode: '+370',\n nativeName: 'Lietuvių',\n englishName: 'Lithuanian',\n currencyCode: 'EUR',\n dateFormat: 'YYYY-MM-DD',\n },\n\n // 라트비아어\n lv: {\n locale: 'lv',\n countryCode: 'LV',\n flag: '🇱🇻',\n dialCode: '+371',\n nativeName: 'Latviešu',\n englishName: 'Latvian',\n currencyCode: 'EUR',\n dateFormat: 'DD.MM.YYYY.',\n },\n\n // 에스토니아어\n et: {\n locale: 'et',\n countryCode: 'EE',\n flag: '🇪🇪',\n dialCode: '+372',\n nativeName: 'Eesti',\n englishName: 'Estonian',\n currencyCode: 'EUR',\n dateFormat: 'DD.MM.YYYY',\n },\n\n // 그리스어\n el: {\n locale: 'el',\n countryCode: 'GR',\n flag: '🇬🇷',\n dialCode: '+30',\n nativeName: 'Ελληνικά',\n englishName: 'Greek',\n currencyCode: 'EUR',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 페르시아어\n fa: {\n locale: 'fa',\n countryCode: 'IR',\n flag: '🇮🇷',\n dialCode: '+98',\n nativeName: 'فارسی',\n englishName: 'Persian',\n rtl: true,\n currencyCode: 'IRR',\n dateFormat: 'YYYY/MM/DD',\n },\n\n // 히브리어\n he: {\n locale: 'he',\n countryCode: 'IL',\n flag: '🇮🇱',\n dialCode: '+972',\n nativeName: 'עברית',\n englishName: 'Hebrew',\n rtl: true,\n currencyCode: 'ILS',\n dateFormat: 'DD/MM/YYYY',\n },\n\n // 스와힐리어\n sw: {\n locale: 'sw',\n countryCode: 'KE',\n flag: '🇰🇪',\n dialCode: '+254',\n nativeName: 'Kiswahili',\n englishName: 'Swahili',\n currencyCode: 'KES',\n dateFormat: 'DD/MM/YYYY',\n },\n};\n\n/**\n * Locale 정보 가져오기\n *\n * @param locale - Locale 코드 (예: 'ko', 'en', 'ja')\n * @returns LocaleInfo 또는 undefined\n *\n * @example\n * ```typescript\n * const koInfo = getLocaleInfo('ko');\n * console.log(koInfo.flag); // 🇰🇷\n * console.log(koInfo.dialCode); // +82\n * ```\n */\nexport function getLocaleInfo(locale: string): LocaleInfo | undefined\n{\n return LOCALE_INFO_MAP[locale as SupportedLocale];\n}\n\n/**\n * 지원하는 모든 Locale 목록 가져오기\n *\n * @returns Locale 코드 배열\n */\nexport function getSupportedLocales(): SupportedLocale[]\n{\n return Object.keys(LOCALE_INFO_MAP) as SupportedLocale[];\n}\n\n/**\n * 국기 이모지만 가져오기\n *\n * @param locale - Locale 코드\n * @returns 국기 이모지 또는 빈 문자열\n *\n * @example\n * ```typescript\n * getFlag('ko'); // 🇰🇷\n * getFlag('en'); // 🇺🇸\n * ```\n */\nexport function getFlag(locale: string): string\n{\n return LOCALE_INFO_MAP[locale as SupportedLocale]?.flag ?? '';\n}\n\n/**\n * 전화번호 국가 코드 가져오기\n *\n * @param locale - Locale 코드\n * @returns 전화번호 코드 또는 빈 문자열\n *\n * @example\n * ```typescript\n * getDialCode('ko'); // +82\n * getDialCode('en'); // +1\n * ```\n */\nexport function getDialCode(locale: string): string\n{\n return LOCALE_INFO_MAP[locale as SupportedLocale]?.dialCode ?? '';\n}\n\n/**\n * RTL (Right-to-Left) 여부 확인\n *\n * @param locale - Locale 코드\n * @returns RTL 여부\n *\n * @example\n * ```typescript\n * isRTL('ar'); // true (Arabic)\n * isRTL('ko'); // false (Korean)\n * ```\n */\nexport function isRTL(locale: string): boolean\n{\n return LOCALE_INFO_MAP[locale as SupportedLocale]?.rtl ?? false;\n}"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GeneratorTrigger, Generator } from '@spfn/core/codegen';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Label Sync Generator
|
|
5
|
+
*
|
|
6
|
+
* File-based label sync with JSON definitions
|
|
7
|
+
*
|
|
8
|
+
* Structure:
|
|
9
|
+
* lib/labels/
|
|
10
|
+
* layout/ # Section name
|
|
11
|
+
* nav.json # Label definitions
|
|
12
|
+
* footer.json
|
|
13
|
+
* homepage/
|
|
14
|
+
* hero.json
|
|
15
|
+
*
|
|
16
|
+
* Features:
|
|
17
|
+
* - Incremental updates: syncs only changed section on file change
|
|
18
|
+
* - Full sync on file add/delete or manual trigger
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
interface LabelSyncGeneratorConfig {
|
|
22
|
+
labelsDir?: string;
|
|
23
|
+
runOn?: GeneratorTrigger[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create label sync generator
|
|
27
|
+
*
|
|
28
|
+
* Supports incremental updates when single files change
|
|
29
|
+
*/
|
|
30
|
+
declare function createLabelSyncGenerator(config?: LabelSyncGeneratorConfig): Generator;
|
|
31
|
+
|
|
32
|
+
export { createLabelSyncGenerator as c };
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CMS Labels Contracts
|
|
5
|
+
*
|
|
6
|
+
* 라벨 메타데이터 관리 API
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* GET /_cms/labels - 라벨 목록 조회
|
|
10
|
+
*/
|
|
11
|
+
declare const getLabelsContract: {
|
|
12
|
+
readonly method: "GET";
|
|
13
|
+
readonly path: "/_cms/labels";
|
|
14
|
+
readonly query: _sinclair_typebox.TObject<{
|
|
15
|
+
section: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
16
|
+
limit: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
17
|
+
offset: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
18
|
+
includeDefaultValues: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
|
|
19
|
+
}>;
|
|
20
|
+
readonly response: _sinclair_typebox.TObject<{
|
|
21
|
+
labels: _sinclair_typebox.TArray<_sinclair_typebox.TObject<{
|
|
22
|
+
id: _sinclair_typebox.TNumber;
|
|
23
|
+
key: _sinclair_typebox.TString;
|
|
24
|
+
section: _sinclair_typebox.TString;
|
|
25
|
+
type: _sinclair_typebox.TString;
|
|
26
|
+
publishedVersion: _sinclair_typebox.TUnion<[_sinclair_typebox.TNumber, _sinclair_typebox.TNull]>;
|
|
27
|
+
createdBy: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
28
|
+
createdAt: _sinclair_typebox.TString;
|
|
29
|
+
updatedAt: _sinclair_typebox.TString;
|
|
30
|
+
defaultValue: _sinclair_typebox.TOptional<_sinclair_typebox.TAny>;
|
|
31
|
+
}>>;
|
|
32
|
+
total: _sinclair_typebox.TNumber;
|
|
33
|
+
limit: _sinclair_typebox.TNumber;
|
|
34
|
+
offset: _sinclair_typebox.TNumber;
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* POST /_cms/labels - 새 라벨 생성
|
|
39
|
+
*/
|
|
40
|
+
declare const createLabelContract: {
|
|
41
|
+
readonly method: "POST";
|
|
42
|
+
readonly path: "/_cms/labels";
|
|
43
|
+
readonly body: _sinclair_typebox.TObject<{
|
|
44
|
+
key: _sinclair_typebox.TString;
|
|
45
|
+
section: _sinclair_typebox.TString;
|
|
46
|
+
type: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"text">, _sinclair_typebox.TLiteral<"image">, _sinclair_typebox.TLiteral<"video">, _sinclair_typebox.TLiteral<"file">, _sinclair_typebox.TLiteral<"object">]>;
|
|
47
|
+
createdBy: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
48
|
+
}>;
|
|
49
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
50
|
+
id: _sinclair_typebox.TNumber;
|
|
51
|
+
key: _sinclair_typebox.TString;
|
|
52
|
+
section: _sinclair_typebox.TString;
|
|
53
|
+
type: _sinclair_typebox.TString;
|
|
54
|
+
publishedVersion: _sinclair_typebox.TUnion<[_sinclair_typebox.TNumber, _sinclair_typebox.TNull]>;
|
|
55
|
+
createdBy: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
56
|
+
createdAt: _sinclair_typebox.TString;
|
|
57
|
+
updatedAt: _sinclair_typebox.TString;
|
|
58
|
+
}>, _sinclair_typebox.TObject<{
|
|
59
|
+
error: _sinclair_typebox.TString;
|
|
60
|
+
key: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
61
|
+
}>]>;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* GET /_cms/labels/:id - 라벨 단건 조회
|
|
65
|
+
*/
|
|
66
|
+
declare const getLabelContract: {
|
|
67
|
+
readonly method: "GET";
|
|
68
|
+
readonly path: "/_cms/labels/:id";
|
|
69
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
70
|
+
id: _sinclair_typebox.TString;
|
|
71
|
+
}>;
|
|
72
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
73
|
+
id: _sinclair_typebox.TNumber;
|
|
74
|
+
key: _sinclair_typebox.TString;
|
|
75
|
+
section: _sinclair_typebox.TString;
|
|
76
|
+
type: _sinclair_typebox.TString;
|
|
77
|
+
publishedVersion: _sinclair_typebox.TUnion<[_sinclair_typebox.TNumber, _sinclair_typebox.TNull]>;
|
|
78
|
+
createdBy: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
79
|
+
createdAt: _sinclair_typebox.TString;
|
|
80
|
+
updatedAt: _sinclair_typebox.TString;
|
|
81
|
+
}>, _sinclair_typebox.TObject<{
|
|
82
|
+
error: _sinclair_typebox.TString;
|
|
83
|
+
}>]>;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* PATCH /_cms/labels/:id - 라벨 메타데이터 수정
|
|
87
|
+
*/
|
|
88
|
+
declare const updateLabelContract: {
|
|
89
|
+
readonly method: "PATCH";
|
|
90
|
+
readonly path: "/_cms/labels/:id";
|
|
91
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
92
|
+
id: _sinclair_typebox.TString;
|
|
93
|
+
}>;
|
|
94
|
+
readonly body: _sinclair_typebox.TObject<{
|
|
95
|
+
section: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
96
|
+
type: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"text">, _sinclair_typebox.TLiteral<"image">, _sinclair_typebox.TLiteral<"video">, _sinclair_typebox.TLiteral<"file">, _sinclair_typebox.TLiteral<"object">]>>;
|
|
97
|
+
}>;
|
|
98
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
99
|
+
id: _sinclair_typebox.TNumber;
|
|
100
|
+
key: _sinclair_typebox.TString;
|
|
101
|
+
section: _sinclair_typebox.TString;
|
|
102
|
+
type: _sinclair_typebox.TString;
|
|
103
|
+
publishedVersion: _sinclair_typebox.TUnion<[_sinclair_typebox.TNumber, _sinclair_typebox.TNull]>;
|
|
104
|
+
createdBy: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
105
|
+
createdAt: _sinclair_typebox.TString;
|
|
106
|
+
updatedAt: _sinclair_typebox.TString;
|
|
107
|
+
}>, _sinclair_typebox.TObject<{
|
|
108
|
+
error: _sinclair_typebox.TString;
|
|
109
|
+
}>]>;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* DELETE /_cms/labels/:id - 라벨 삭제
|
|
113
|
+
*/
|
|
114
|
+
declare const deleteLabelContract: {
|
|
115
|
+
readonly method: "DELETE";
|
|
116
|
+
readonly path: "/_cms/labels/:id";
|
|
117
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
118
|
+
id: _sinclair_typebox.TString;
|
|
119
|
+
}>;
|
|
120
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
121
|
+
success: _sinclair_typebox.TBoolean;
|
|
122
|
+
id: _sinclair_typebox.TNumber;
|
|
123
|
+
}>, _sinclair_typebox.TObject<{
|
|
124
|
+
error: _sinclair_typebox.TString;
|
|
125
|
+
}>]>;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* GET /_cms/labels/by-key/:key - Key로 라벨 조회
|
|
129
|
+
*/
|
|
130
|
+
declare const getLabelByKeyContract: {
|
|
131
|
+
readonly method: "GET";
|
|
132
|
+
readonly path: "/_cms/labels/by-key/:key";
|
|
133
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
134
|
+
key: _sinclair_typebox.TString;
|
|
135
|
+
}>;
|
|
136
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
137
|
+
id: _sinclair_typebox.TNumber;
|
|
138
|
+
key: _sinclair_typebox.TString;
|
|
139
|
+
section: _sinclair_typebox.TString;
|
|
140
|
+
type: _sinclair_typebox.TString;
|
|
141
|
+
publishedVersion: _sinclair_typebox.TUnion<[_sinclair_typebox.TNumber, _sinclair_typebox.TNull]>;
|
|
142
|
+
createdBy: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
143
|
+
createdAt: _sinclair_typebox.TString;
|
|
144
|
+
updatedAt: _sinclair_typebox.TString;
|
|
145
|
+
}>, _sinclair_typebox.TObject<{
|
|
146
|
+
error: _sinclair_typebox.TString;
|
|
147
|
+
key: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
148
|
+
}>]>;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export { createLabelContract, deleteLabelContract, getLabelByKeyContract, getLabelContract, getLabelsContract, updateLabelContract };
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// src/lib/contracts/labels.ts
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
var getLabelsContract = {
|
|
4
|
+
method: "GET",
|
|
5
|
+
path: "/_cms/labels",
|
|
6
|
+
query: Type.Object({
|
|
7
|
+
section: Type.Optional(Type.String({ description: "\uC139\uC158\uC73C\uB85C \uD544\uD130\uB9C1 (\uC608: home, why-futureplay)" })),
|
|
8
|
+
limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100, default: 20, description: "\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218" })),
|
|
9
|
+
offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: "\uC2DC\uC791 \uC624\uD504\uC14B" })),
|
|
10
|
+
includeDefaultValues: Type.Optional(Type.Boolean({ description: "\uAE30\uBCF8\uAC12 \uD3EC\uD568 \uC5EC\uBD80", default: false }))
|
|
11
|
+
}),
|
|
12
|
+
response: Type.Object({
|
|
13
|
+
labels: Type.Array(Type.Object({
|
|
14
|
+
id: Type.Number(),
|
|
15
|
+
key: Type.String(),
|
|
16
|
+
section: Type.String(),
|
|
17
|
+
type: Type.String(),
|
|
18
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
19
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
20
|
+
createdAt: Type.String(),
|
|
21
|
+
updatedAt: Type.String(),
|
|
22
|
+
defaultValue: Type.Optional(Type.Any({ description: "\uB77C\uBCA8 \uC815\uC758 \uD30C\uC77C\uC758 \uAE30\uBCF8\uAC12" }))
|
|
23
|
+
})),
|
|
24
|
+
total: Type.Number(),
|
|
25
|
+
limit: Type.Number(),
|
|
26
|
+
offset: Type.Number()
|
|
27
|
+
})
|
|
28
|
+
};
|
|
29
|
+
var createLabelContract = {
|
|
30
|
+
method: "POST",
|
|
31
|
+
path: "/_cms/labels",
|
|
32
|
+
body: Type.Object({
|
|
33
|
+
key: Type.String({
|
|
34
|
+
description: "\uACE0\uC720 \uD0A4 (\uC608: home.hero.title)",
|
|
35
|
+
pattern: "^[a-z0-9-]+\\.[a-z0-9-]+\\.[a-z0-9-]+$"
|
|
36
|
+
}),
|
|
37
|
+
section: Type.String({
|
|
38
|
+
description: "\uC139\uC158 \uC774\uB984 (\uC608: home, why-futureplay)",
|
|
39
|
+
pattern: "^[a-z0-9-]+$"
|
|
40
|
+
}),
|
|
41
|
+
type: Type.Union([
|
|
42
|
+
Type.Literal("text"),
|
|
43
|
+
Type.Literal("image"),
|
|
44
|
+
Type.Literal("video"),
|
|
45
|
+
Type.Literal("file"),
|
|
46
|
+
Type.Literal("object")
|
|
47
|
+
], { description: "\uAC12 \uD0C0\uC785" }),
|
|
48
|
+
createdBy: Type.Optional(Type.String({ description: "\uC0DD\uC131\uC790 ID" }))
|
|
49
|
+
}),
|
|
50
|
+
response: Type.Union([
|
|
51
|
+
Type.Object({
|
|
52
|
+
id: Type.Number(),
|
|
53
|
+
key: Type.String(),
|
|
54
|
+
section: Type.String(),
|
|
55
|
+
type: Type.String(),
|
|
56
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
57
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
58
|
+
createdAt: Type.String(),
|
|
59
|
+
updatedAt: Type.String()
|
|
60
|
+
}),
|
|
61
|
+
Type.Object({
|
|
62
|
+
error: Type.String(),
|
|
63
|
+
key: Type.Optional(Type.String())
|
|
64
|
+
})
|
|
65
|
+
])
|
|
66
|
+
};
|
|
67
|
+
var getLabelContract = {
|
|
68
|
+
method: "GET",
|
|
69
|
+
path: "/_cms/labels/:id",
|
|
70
|
+
params: Type.Object({
|
|
71
|
+
id: Type.String({ description: "\uB77C\uBCA8 ID" })
|
|
72
|
+
}),
|
|
73
|
+
response: Type.Union([
|
|
74
|
+
Type.Object({
|
|
75
|
+
id: Type.Number(),
|
|
76
|
+
key: Type.String(),
|
|
77
|
+
section: Type.String(),
|
|
78
|
+
type: Type.String(),
|
|
79
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
80
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
81
|
+
createdAt: Type.String(),
|
|
82
|
+
updatedAt: Type.String()
|
|
83
|
+
}),
|
|
84
|
+
Type.Object({
|
|
85
|
+
error: Type.String()
|
|
86
|
+
})
|
|
87
|
+
])
|
|
88
|
+
};
|
|
89
|
+
var updateLabelContract = {
|
|
90
|
+
method: "PATCH",
|
|
91
|
+
path: "/_cms/labels/:id",
|
|
92
|
+
params: Type.Object({
|
|
93
|
+
id: Type.String({ description: "\uB77C\uBCA8 ID" })
|
|
94
|
+
}),
|
|
95
|
+
body: Type.Object({
|
|
96
|
+
section: Type.Optional(Type.String({ description: "\uC139\uC158 \uBCC0\uACBD" })),
|
|
97
|
+
type: Type.Optional(Type.Union([
|
|
98
|
+
Type.Literal("text"),
|
|
99
|
+
Type.Literal("image"),
|
|
100
|
+
Type.Literal("video"),
|
|
101
|
+
Type.Literal("file"),
|
|
102
|
+
Type.Literal("object")
|
|
103
|
+
]))
|
|
104
|
+
}),
|
|
105
|
+
response: Type.Union([
|
|
106
|
+
Type.Object({
|
|
107
|
+
id: Type.Number(),
|
|
108
|
+
key: Type.String(),
|
|
109
|
+
section: Type.String(),
|
|
110
|
+
type: Type.String(),
|
|
111
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
112
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
113
|
+
createdAt: Type.String(),
|
|
114
|
+
updatedAt: Type.String()
|
|
115
|
+
}),
|
|
116
|
+
Type.Object({
|
|
117
|
+
error: Type.String()
|
|
118
|
+
})
|
|
119
|
+
])
|
|
120
|
+
};
|
|
121
|
+
var deleteLabelContract = {
|
|
122
|
+
method: "DELETE",
|
|
123
|
+
path: "/_cms/labels/:id",
|
|
124
|
+
params: Type.Object({
|
|
125
|
+
id: Type.String({ description: "\uB77C\uBCA8 ID" })
|
|
126
|
+
}),
|
|
127
|
+
response: Type.Union([
|
|
128
|
+
Type.Object({
|
|
129
|
+
success: Type.Boolean(),
|
|
130
|
+
id: Type.Number()
|
|
131
|
+
}),
|
|
132
|
+
Type.Object({
|
|
133
|
+
error: Type.String()
|
|
134
|
+
})
|
|
135
|
+
])
|
|
136
|
+
};
|
|
137
|
+
var getLabelByKeyContract = {
|
|
138
|
+
method: "GET",
|
|
139
|
+
path: "/_cms/labels/by-key/:key",
|
|
140
|
+
params: Type.Object({
|
|
141
|
+
key: Type.String({ description: "\uB77C\uBCA8 Key (\uC608: home.hero.title)" })
|
|
142
|
+
}),
|
|
143
|
+
response: Type.Union([
|
|
144
|
+
Type.Object({
|
|
145
|
+
id: Type.Number(),
|
|
146
|
+
key: Type.String(),
|
|
147
|
+
section: Type.String(),
|
|
148
|
+
type: Type.String(),
|
|
149
|
+
publishedVersion: Type.Union([Type.Number(), Type.Null()]),
|
|
150
|
+
createdBy: Type.Union([Type.String(), Type.Null()]),
|
|
151
|
+
createdAt: Type.String(),
|
|
152
|
+
updatedAt: Type.String()
|
|
153
|
+
}),
|
|
154
|
+
Type.Object({
|
|
155
|
+
error: Type.String(),
|
|
156
|
+
key: Type.Optional(Type.String())
|
|
157
|
+
})
|
|
158
|
+
])
|
|
159
|
+
};
|
|
160
|
+
export {
|
|
161
|
+
createLabelContract,
|
|
162
|
+
deleteLabelContract,
|
|
163
|
+
getLabelByKeyContract,
|
|
164
|
+
getLabelContract,
|
|
165
|
+
getLabelsContract,
|
|
166
|
+
updateLabelContract
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/contracts/labels.ts"],"sourcesContent":["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 /_cms/labels - 라벨 목록 조회\n */\nexport const getLabelsContract = {\n method: 'GET' as const,\n path: '/_cms/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 includeDefaultValues: Type.Optional(Type.Boolean({ description: '기본값 포함 여부', default: false }))\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 defaultValue: Type.Optional(Type.Any({ description: '라벨 정의 파일의 기본값' }))\n })),\n total: Type.Number(),\n limit: Type.Number(),\n offset: Type.Number()\n })\n} as const satisfies RouteContract;\n\n/**\n * POST /_cms/labels - 새 라벨 생성\n */\nexport const createLabelContract = {\n method: 'POST' as const,\n path: '/_cms/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 /_cms/labels/:id - 라벨 단건 조회\n */\nexport const getLabelContract = {\n method: 'GET' as const,\n path: '/_cms/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 /_cms/labels/:id - 라벨 메타데이터 수정\n */\nexport const updateLabelContract = {\n method: 'PATCH' as const,\n path: '/_cms/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 /_cms/labels/:id - 라벨 삭제\n */\nexport const deleteLabelContract = {\n method: 'DELETE' as const,\n path: '/_cms/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 /_cms/labels/by-key/:key - Key로 라벨 조회\n */\nexport const getLabelByKeyContract = {\n method: 'GET' as const,\n path: '/_cms/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;"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GET /_cms/published-cache
|
|
5
|
+
* 발행된 콘텐츠 캐시 조회 (단일 또는 여러 섹션)
|
|
6
|
+
*/
|
|
7
|
+
declare const getPublishedCacheContract: {
|
|
8
|
+
readonly method: "GET";
|
|
9
|
+
readonly path: "/_cms/published-cache";
|
|
10
|
+
readonly query: _sinclair_typebox.TObject<{
|
|
11
|
+
sections: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TArray<_sinclair_typebox.TString>]>;
|
|
12
|
+
locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
13
|
+
}>;
|
|
14
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TArray<_sinclair_typebox.TObject<{
|
|
15
|
+
section: _sinclair_typebox.TString;
|
|
16
|
+
locale: _sinclair_typebox.TString;
|
|
17
|
+
content: _sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>;
|
|
18
|
+
version: _sinclair_typebox.TNumber;
|
|
19
|
+
publishedAt: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
20
|
+
}>>, _sinclair_typebox.TObject<{
|
|
21
|
+
error: _sinclair_typebox.TString;
|
|
22
|
+
}>]>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* POST /_cms/published-cache
|
|
26
|
+
* 발행된 콘텐츠 캐시 업데이트/생성 (upsert)
|
|
27
|
+
*/
|
|
28
|
+
declare const upsertPublishedCacheContract: {
|
|
29
|
+
readonly method: "POST";
|
|
30
|
+
readonly path: "/_cms/published-cache";
|
|
31
|
+
readonly body: _sinclair_typebox.TObject<{
|
|
32
|
+
section: _sinclair_typebox.TString;
|
|
33
|
+
locale: _sinclair_typebox.TString;
|
|
34
|
+
content: _sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>;
|
|
35
|
+
version: _sinclair_typebox.TNumber;
|
|
36
|
+
}>;
|
|
37
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
38
|
+
section: _sinclair_typebox.TString;
|
|
39
|
+
locale: _sinclair_typebox.TString;
|
|
40
|
+
content: _sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>;
|
|
41
|
+
version: _sinclair_typebox.TNumber;
|
|
42
|
+
publishedAt: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
43
|
+
}>, _sinclair_typebox.TObject<{
|
|
44
|
+
error: _sinclair_typebox.TString;
|
|
45
|
+
}>]>;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { getPublishedCacheContract, upsertPublishedCacheContract };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// src/lib/contracts/published-cache.ts
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
var SectionData = Type.Object({
|
|
4
|
+
section: Type.String(),
|
|
5
|
+
locale: Type.String(),
|
|
6
|
+
content: Type.Record(Type.String(), Type.Any()),
|
|
7
|
+
version: Type.Number(),
|
|
8
|
+
publishedAt: Type.Union([Type.String(), Type.Null()])
|
|
9
|
+
});
|
|
10
|
+
var getPublishedCacheContract = {
|
|
11
|
+
method: "GET",
|
|
12
|
+
path: "/_cms/published-cache",
|
|
13
|
+
query: Type.Object({
|
|
14
|
+
sections: Type.Union([
|
|
15
|
+
Type.String({ description: "\uB2E8\uC77C \uC139\uC158 \uC774\uB984 (\uC608: home)" }),
|
|
16
|
+
Type.Array(Type.String(), { description: '\uC5EC\uB7EC \uC139\uC158 \uC774\uB984 (\uC608: ["home", "footer"])' })
|
|
17
|
+
]),
|
|
18
|
+
locale: Type.Optional(Type.String({ default: "ko", description: "\uC5B8\uC5B4 \uCF54\uB4DC" }))
|
|
19
|
+
}),
|
|
20
|
+
response: Type.Union([
|
|
21
|
+
// 성공: 항상 배열로 반환
|
|
22
|
+
Type.Array(SectionData),
|
|
23
|
+
// 에러
|
|
24
|
+
Type.Object({
|
|
25
|
+
error: Type.String()
|
|
26
|
+
})
|
|
27
|
+
])
|
|
28
|
+
};
|
|
29
|
+
var upsertPublishedCacheContract = {
|
|
30
|
+
method: "POST",
|
|
31
|
+
path: "/_cms/published-cache",
|
|
32
|
+
body: Type.Object({
|
|
33
|
+
section: Type.String({ description: "\uC139\uC158 \uC774\uB984 (\uC608: home)" }),
|
|
34
|
+
locale: Type.String({ description: "\uC5B8\uC5B4 \uCF54\uB4DC (\uC608: ko, en, ja)" }),
|
|
35
|
+
content: Type.Record(Type.String(), Type.Any(), { description: "\uBC1C\uD589\uD560 \uCF58\uD150\uCE20 (key-value \uD615\uD0DC)" }),
|
|
36
|
+
version: Type.Number({ description: "\uBC84\uC804 \uBC88\uD638" })
|
|
37
|
+
}),
|
|
38
|
+
response: Type.Union([
|
|
39
|
+
SectionData,
|
|
40
|
+
Type.Object({
|
|
41
|
+
error: Type.String()
|
|
42
|
+
})
|
|
43
|
+
])
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
getPublishedCacheContract,
|
|
47
|
+
upsertPublishedCacheContract
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=published-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/contracts/published-cache.ts"],"sourcesContent":["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 /_cms/published-cache\n * 발행된 콘텐츠 캐시 조회 (단일 또는 여러 섹션)\n */\nexport const getPublishedCacheContract = {\n method: 'GET' as const,\n path: '/_cms/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\n/**\n * POST /_cms/published-cache\n * 발행된 콘텐츠 캐시 업데이트/생성 (upsert)\n */\nexport const upsertPublishedCacheContract = {\n method: 'POST' as const,\n path: '/_cms/published-cache',\n body: Type.Object({\n section: Type.String({ description: '섹션 이름 (예: home)' }),\n locale: Type.String({ description: '언어 코드 (예: ko, en, ja)' }),\n content: Type.Record(Type.String(), Type.Any(), { description: '발행할 콘텐츠 (key-value 형태)' }),\n version: Type.Number({ description: '버전 번호' })\n }),\n response: Type.Union([\n SectionData,\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;"],"mappings":";AAAA,SAAS,YAAY;AAGrB,IAAM,cAAc,KAAK,OAAO;AAAA,EAC5B,SAAS,KAAK,OAAO;AAAA,EACrB,QAAQ,KAAK,OAAO;AAAA,EACpB,SAAS,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,CAAC;AAAA,EAC9C,SAAS,KAAK,OAAO;AAAA,EACrB,aAAa,KAAK,MAAM,CAAC,KAAK,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC;AACxD,CAAC;AAMM,IAAM,4BAA4B;AAAA,EACrC,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO,KAAK,OAAO;AAAA,IACf,UAAU,KAAK,MAAM;AAAA,MACjB,KAAK,OAAO,EAAE,aAAa,wDAAqB,CAAC;AAAA,MACjD,KAAK,MAAM,KAAK,OAAO,GAAG,EAAE,aAAa,sEAAmC,CAAC;AAAA,IACjF,CAAC;AAAA,IACD,QAAQ,KAAK,SAAS,KAAK,OAAO,EAAE,SAAS,MAAM,aAAa,4BAAQ,CAAC,CAAC;AAAA,EAC9E,CAAC;AAAA,EACD,UAAU,KAAK,MAAM;AAAA;AAAA,IAEjB,KAAK,MAAM,WAAW;AAAA;AAAA,IAEtB,KAAK,OAAO;AAAA,MACR,OAAO,KAAK,OAAO;AAAA,IACvB,CAAC;AAAA,EACL,CAAC;AACL;AAMO,IAAM,+BAA+B;AAAA,EACxC,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM,KAAK,OAAO;AAAA,IACd,SAAS,KAAK,OAAO,EAAE,aAAa,2CAAkB,CAAC;AAAA,IACvD,QAAQ,KAAK,OAAO,EAAE,aAAa,iDAAwB,CAAC;AAAA,IAC5D,SAAS,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,GAAG,EAAE,aAAa,iEAAyB,CAAC;AAAA,IACzF,SAAS,KAAK,OAAO,EAAE,aAAa,4BAAQ,CAAC;AAAA,EACjD,CAAC;AAAA,EACD,UAAU,KAAK,MAAM;AAAA,IACjB;AAAA,IACA,KAAK,OAAO;AAAA,MACR,OAAO,KAAK,OAAO;AAAA,IACvB,CAAC;AAAA,EACL,CAAC;AACL;","names":[]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* POST /_cms/values/:labelId - 라벨 값 저장
|
|
5
|
+
* - version: null → Draft 저장 (덮어쓰기)
|
|
6
|
+
* - version: number → Published 버전 생성 (불변)
|
|
7
|
+
*/
|
|
8
|
+
declare const saveValuesContract: {
|
|
9
|
+
readonly method: "POST";
|
|
10
|
+
readonly path: "/_cms/values/:labelId";
|
|
11
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
12
|
+
labelId: _sinclair_typebox.TString;
|
|
13
|
+
}>;
|
|
14
|
+
readonly body: _sinclair_typebox.TObject<{
|
|
15
|
+
version: _sinclair_typebox.TUnion<[_sinclair_typebox.TNull, _sinclair_typebox.TNumber]>;
|
|
16
|
+
values: _sinclair_typebox.TArray<_sinclair_typebox.TObject<{
|
|
17
|
+
locale: _sinclair_typebox.TString;
|
|
18
|
+
breakpoint: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"sm">, _sinclair_typebox.TLiteral<"md">, _sinclair_typebox.TLiteral<"lg">, _sinclair_typebox.TLiteral<"xl">, _sinclair_typebox.TLiteral<"2xl">, _sinclair_typebox.TNull]>>;
|
|
19
|
+
value: _sinclair_typebox.TObject<{
|
|
20
|
+
type: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"text">, _sinclair_typebox.TLiteral<"image">, _sinclair_typebox.TLiteral<"video">, _sinclair_typebox.TLiteral<"file">, _sinclair_typebox.TLiteral<"object">]>;
|
|
21
|
+
content: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
22
|
+
url: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
23
|
+
alt: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
24
|
+
width: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
25
|
+
height: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
26
|
+
thumbnail: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
27
|
+
duration: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
28
|
+
filename: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
29
|
+
size: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
|
|
30
|
+
fields: _sinclair_typebox.TOptional<_sinclair_typebox.TAny>;
|
|
31
|
+
}>;
|
|
32
|
+
}>>;
|
|
33
|
+
}>;
|
|
34
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
35
|
+
success: _sinclair_typebox.TBoolean;
|
|
36
|
+
saved: _sinclair_typebox.TNumber;
|
|
37
|
+
version: _sinclair_typebox.TUnion<[_sinclair_typebox.TNull, _sinclair_typebox.TNumber]>;
|
|
38
|
+
}>, _sinclair_typebox.TObject<{
|
|
39
|
+
error: _sinclair_typebox.TString;
|
|
40
|
+
}>]>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* GET /_cms/values/:labelId/:version - 특정 버전의 값 조회
|
|
44
|
+
*/
|
|
45
|
+
declare const getValuesContract: {
|
|
46
|
+
readonly method: "GET";
|
|
47
|
+
readonly path: "/_cms/values/:labelId/:version";
|
|
48
|
+
readonly params: _sinclair_typebox.TObject<{
|
|
49
|
+
labelId: _sinclair_typebox.TString;
|
|
50
|
+
version: _sinclair_typebox.TString;
|
|
51
|
+
}>;
|
|
52
|
+
readonly query: _sinclair_typebox.TObject<{
|
|
53
|
+
locale: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
54
|
+
breakpoint: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
|
|
55
|
+
}>;
|
|
56
|
+
readonly response: _sinclair_typebox.TUnion<[_sinclair_typebox.TObject<{
|
|
57
|
+
labelId: _sinclair_typebox.TNumber;
|
|
58
|
+
version: _sinclair_typebox.TNumber;
|
|
59
|
+
values: _sinclair_typebox.TArray<_sinclair_typebox.TObject<{
|
|
60
|
+
id: _sinclair_typebox.TNumber;
|
|
61
|
+
locale: _sinclair_typebox.TString;
|
|
62
|
+
breakpoint: _sinclair_typebox.TUnion<[_sinclair_typebox.TString, _sinclair_typebox.TNull]>;
|
|
63
|
+
value: _sinclair_typebox.TAny;
|
|
64
|
+
createdAt: _sinclair_typebox.TString;
|
|
65
|
+
}>>;
|
|
66
|
+
}>, _sinclair_typebox.TObject<{
|
|
67
|
+
error: _sinclair_typebox.TString;
|
|
68
|
+
}>]>;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export { getValuesContract, saveValuesContract };
|