@zalkera/client 0.21.6 → 0.21.8

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/llms.txt CHANGED
@@ -179,7 +179,7 @@ visitorIp(req.headers, { trustedHops: 2 }); // 예: CDN + 로드밸런서
179
179
  ### 계약 헬퍼 — 직접 짜지 말고 이걸 부른다
180
180
 
181
181
  이 패키지는 **API 클라이언트이면서 계약 부품의 운반체**다. 아래는 전부 `@zalkera/client` 에서 import 한다 —
182
- 프로젝트 안에 `lib/safeUrl.ts`·`sections/parse.ts` 를 새로 만들지 마라(사본이 갈라지면 수리가 안 퍼진다).
182
+ 프로젝트 안에 `src/lib/safeUrl.ts`·`sections/parse.ts` 를 새로 만들지 마라(사본이 갈라지면 수리가 안 퍼진다).
183
183
 
184
184
  - `safeLinkUrl(raw)` → `string` — **모든 `href` 는 이걸 태운다.** 콘솔 입력이라 `javascript:` 가 들어올 수 있다(저장형 XSS).
185
185
  - `parseConfig<T>(config)` → `T | null` — 섹션 `config` JSON 파싱. **절대 throw 하지 않는다**(실패 시 null).
@@ -191,7 +191,7 @@ visitorIp(req.headers, { trustedHops: 2 }); // 예: CDN + 로드밸런서
191
191
  빈 배열은 truthy 라 `if (items)` 로 결측을 판별하면 안 된다 — `items.length` 을 봐라.
192
192
  - 위 가드로 **필수 값이 없으면 그 섹션만 안 그린다**. 페이지 전체가 죽으면 안 된다.
193
193
  - `mediaSrc(assetId)` → `/media/{id}` **경로 문자열**. 이미지는 전부 이걸 통한다.
194
- 전제: 프로젝트에 `app/media/[id]/route.ts` 프록시 라우트가 있어야 한다(**§4.9 에 전문**).
194
+ 전제: 프로젝트에 `src/app/media/[id]/route.ts` 프록시 라우트가 있어야 한다(**§4.9 에 전문**).
195
195
  이 헬퍼는 경로만 만든다 — 라우트를 안 만들면 이미지가 404 다.
196
196
  - `assetPath(v)` — **소스 참조 표기**(계약 `dialects.reference`)를 읽는다. 숫자 id 를 못 쓰는 자리에서 에셋은
197
197
  레포 `public/` **루트 절대 경로**로 가리킨다. 루트 절대 경로만 통과시킨다(스킴·`//`·`..`·역슬래시 → `undefined`).
@@ -460,7 +460,7 @@ export default async function StaticPage({ params }: { params: Promise<{ slug: s
460
460
  호출**해서 한다(`listProducts()`·`listProductCategories()`). 그러면 "어디에"도 "어떻게"도 소스에 있어,
461
461
  받은 사람의 LLM 이 그 진열을 마음대로 뜯어고칠 수 있다. 같은 홈에 저작물(HERO·FAQ — 선언)과
462
462
  조회(진열 — 직접 호출)가 나란히 사는 것이 정상 형상이다.
463
- - 홈(`app/page.tsx`)은 `loadPageContent("home")` 의 섹션이 있으면 그것을 그리고, 없으면 커머스 골격으로
463
+ - 홈(`src/app/page.tsx`)은 `loadPageContent("home")` 의 섹션이 있으면 그것을 그리고, 없으면 커머스 골격으로
464
464
  강하한다. 콘텐츠 없는 것은 **정상**이다(커머스 테넌트).
465
465
  - **내비(헤더·푸터)도 같은 자리다.** 레이아웃이 `content/nav.json` 의 `header`/`footer` 배열
466
466
  (`{ label, href }` · **배열 순서가 노출 순서**)을 그대로 그린다 — 메뉴를 주는 API 는 없다.
@@ -478,7 +478,7 @@ const header = (nav as { header?: { label: string; href: string }[] }).header ??
478
478
  ### 4.9 미디어 프록시 라우트 (`/media/{id}`) — **필수 부품**
479
479
 
480
480
  `mediaSrc(assetId)` 는 `/media/{id}` **경로 문자열만** 만든다. 그 경로를 받는 라우트는 프로젝트가 갖는다.
481
- **안 만들면 사이트의 이미지가 전부 404 다.** 아래를 `app/media/[id]/route.ts` 로 그대로 복사해라.
481
+ **안 만들면 사이트의 이미지가 전부 404 다.** 아래를 `src/app/media/[id]/route.ts` 로 그대로 복사해라.
482
482
 
483
483
  왜 프록시가 필요한가 — 백엔드 공개 미디어는 둘 다 브라우저·크롤러가 직접 못 쓴다:
484
484
  - `/api/public/media/{id}/url` → **수 분 뒤 만료되는 presigned URL**. ISR 로 캐시된 HTML 안에서 죽고,
@@ -708,7 +708,7 @@ export function merchantReturnPolicyJsonLd(config: SiteConfig, windowDays?: numb
708
708
  실은 값**이라 IP 레이트리밋이 한 줄로 우회되고 IP 기록이 오염된다(실측). ✅ `visitorIp(req.headers)` 를 쓰고
709
709
  프록시 홉 수를 선언한다(§2). `x-real-ip` 폴백도 쓰지 마라 — 세우는 주체가 프록시마다 다르고 안 세우면 위조 자유다.
710
710
  검사기(`zalkera-validate`)가 이 형상을 `[I1]` 경고로 잡는다.
711
- - ❌ **콘텐츠 파일 사이트에서 페이지를 라우트로 신설**(`app/오시는길/page.tsx` 를 새로 짜기). ✅ `content/pages/<slug>.json`
711
+ - ❌ **콘텐츠 파일 사이트에서 페이지를 라우트로 신설**(`src/app/오시는길/page.tsx` 를 새로 짜기). ✅ `content/pages/<slug>.json`
712
712
  **+ 매니페스트 1행**이면 끝이고 라우팅·sitemap 은 이미 있다(§4.8). 라우트를 새로 짜면 그 페이지만 계약 밖으로
713
713
  나가 다음번 "말로 고치기"가 다시 tsx 탐색이 된다 — 실측된 회귀다.
714
714
  - ❌ **콘텐츠 파일에 숫자 id 적기**(`"assetId": 12`·`"productIds": [3,7]`). ✅ 에셋은 `public/` 루트 절대
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zalkera/client",
3
- "version": "0.21.6",
3
+ "version": "0.21.8",
4
4
  "description": "zalkera 헤드리스 CMS 공개 API 클라이언트 (테넌트 사이트용)",
5
5
  "license": "MIT",
6
6
  "author": "Credium Co., Ltd.",