@zalkera/client 0.19.0 → 0.21.0
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 +2 -1
- package/bin/validate-storefront.mjs +700 -16
- package/dist/index.cjs +9 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -6
- package/dist/index.d.ts +19 -6
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/llms.txt +14 -1
- package/package.json +3 -2
package/llms.txt
CHANGED
|
@@ -34,6 +34,7 @@ export const zalkera = createZalkeraClient({
|
|
|
34
34
|
- `.env`: `ZALKERA_API_BASE`, `ZALKERA_TENANT`, (선택)`ZALKERA_STOREFRONT_KEY`. **절대 클라이언트 컴포넌트에서 import 하지 말 것** — baseUrl·시크릿 노출.
|
|
35
35
|
- `secretKey`는 진짜 비밀이다 — `NEXT_PUBLIC_*` 접두사·클라이언트 번들 금지. 서버 `.env`에만. 안 주면 종전대로 `tenant`(X-Tenant)만으로 동작(하위호환).
|
|
36
36
|
- 모든 메서드는 성공 시 데이터를, 실패 시 `ZalkeraError`(`.status`, `.code`, `.isRateLimited`, `.isStorefrontKeyError`, `.validationErrors`)를 던진다.
|
|
37
|
+
- 429 는 두 갈래다: 문의·리드 폼 남발(IP 축)과 **게스트 주문 인가 실패 누적**(주문번호+연락처로 여는 주문/배송/결제 표면 — 정상 조회는 세지 않는다). 서버 사이드에서는 `OrderAccess.context = { clientIp }` 로 방문자를 선언하라.
|
|
37
38
|
- **경로 파라미터는 라이브러리가 인코딩한다** — slug·주문번호·id 를 넘기기 전에 `encodeURIComponent` 를 직접 씌우지 마라(이중 인코딩된다). 쿼리 파라미터도 마찬가지다.
|
|
38
39
|
- **`baseUrl` 은 최종 오리진이어야 한다** — 클라이언트는 리다이렉트를 따라가지 않는다(따라가면 `X-Storefront-Key` 가 다른 오리진으로 샌다). 백엔드가 3xx 를 주면 502 `UPSTREAM_REDIRECT`.
|
|
39
40
|
|
|
@@ -690,7 +691,19 @@ export function merchantReturnPolicyJsonLd(config: SiteConfig, windowDays?: numb
|
|
|
690
691
|
CSS 변수 주입(`style={{"--...": ...}}`)에만 허용된다.
|
|
691
692
|
- ❌ **`var(--oneq-*)` 참조**(정의처 없는 죽은 레거시 토큰). ✅ 테넌트 색은 토큰 유틸리티(`bg-primary`·
|
|
692
693
|
`text-primary` 등, §8)로 쓴다.
|
|
693
|
-
- ❌ 서버에서 `submitInquiry`/`submitLead`/`recordPostView` 부를 때 clientIp
|
|
694
|
+
- ❌ 서버에서 `submitInquiry`/`submitLead`/`recordPostView` 부를 때 clientIp 누락. **축마다 결과가 다르다** —
|
|
695
|
+
`submitInquiry`/`submitLead` 는 **레이트리밋**(테넌트×IP·전 호출 계수 · 문의 3건/60초·리드 30건/60초)이라
|
|
696
|
+
사이트 전체가 한 IP 로 뭉쳐 남의 제출이 내 429 가 된다. `recordPostView` 는 레이트리밋이 아니라
|
|
697
|
+
**조회 dedup**(`sha256(IP|User-Agent)` · 게시글별 · UTC 달력 하루)이라, 뭉치면 **게시글마다 하루 한 건**으로
|
|
698
|
+
접힌다(서빙 인스턴스 수만큼) — 429 가 아니라 집계가 죽는다. ⚠ 그 UA 는 **방문자 것이 아니다**: 서버가
|
|
699
|
+
백엔드를 부르므로 브라우저 UA 는 전달되지 않고 Node fetch 기본값은 상수 `"node"` 다.
|
|
700
|
+
✅ `visitorIp(req.headers)` 로 뽑아 넘긴다. **넘기는 자리가 둘로 갈린다**: 문의·리드·조회는 두 번째 인자가
|
|
701
|
+
곧 컨텍스트라 `(input, {clientIp})`, 주문 계열은 access 안이라 `(no, {phone, context: {clientIp}})` 다.
|
|
702
|
+
⚠ **`confirmPayment` 만 access 가 세 번째**다 — `(no, providerParams, {phone, context: {clientIp}})`.
|
|
703
|
+
두 번째에 넣으면 access 가 `providerParams` 자리에 앉아 헤더가 안 붙는데 인자엔 `clientIp` 가 생겨
|
|
704
|
+
검사기까지 침묵한다.
|
|
705
|
+
틀린 쪽을 쓰면 TS 는 잡지만 **JS 레포는 조용히 통과**한다(헤더가 안 붙는데 파일엔 `clientIp` 가 생긴다).
|
|
706
|
+
검사기(`zalkera-validate`)가 이 형상을 `[I2]` 경고로 잡는다.
|
|
694
707
|
- ❌ **`x-forwarded-for` 첫 엔트리를 clientIp 로 쓰기**(`xff.split(",")[0]`). 첫 엔트리는 **방문자가 요청에 손으로
|
|
695
708
|
실은 값**이라 IP 레이트리밋이 한 줄로 우회되고 IP 기록이 오염된다(실측). ✅ `visitorIp(req.headers)` 를 쓰고
|
|
696
709
|
프록시 홉 수를 선언한다(§2). `x-real-ip` 폴백도 쓰지 마라 — 세우는 주체가 프록시마다 다르고 안 세우면 위조 자유다.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zalkera/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "zalkera 헤드리스 CMS 공개 API 클라이언트 (테넌트 사이트용)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Credium Co., Ltd.",
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
"typecheck": "tsc --noEmit",
|
|
49
49
|
"test": "vitest run",
|
|
50
50
|
"test:watch": "vitest",
|
|
51
|
-
"prepublishOnly": "npm run typecheck && npm test && npm run build"
|
|
51
|
+
"prepublishOnly": "npm run typecheck && npm test && npm run check:published && npm run build",
|
|
52
|
+
"check:published": "node scripts/check-published-drift.mjs"
|
|
52
53
|
},
|
|
53
54
|
"engines": {
|
|
54
55
|
"node": ">=18"
|