@zalkera/client 0.21.0 → 0.21.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.
@@ -153,6 +153,22 @@ function resolveSourceRoot() {
153
153
 
154
154
  const root = resolveSourceRoot();
155
155
 
156
+ /**
157
+ * 레포 루트. **소스 루트의 부모가 아니다** — 소스 루트가 레포 루트 자신일 수 있다.
158
+ *
159
+ * ⚠ 종전엔 7곳이 각자 `resolve(root, "..")` 를 썼다. BYO 레포처럼 `app/` 이 레포 루트에 바로 있으면
160
+ * 그 좌표가 **레포 밖**을 가리켜, 이웃 디렉터리의 `.env` 가 이 레포의 E3 로 잡히고(관문 rc=1)
161
+ * 자기 `content/`·`next.config`·`AGENTS.md` 는 조용히 스킵됐다 — `build.sh` 가 BYO 에 쓰는
162
+ * `--gate .` 경로에서 **N1 거짓 오류로 관문이 섰다**(두 심의자가 독립적으로 같은 자리를 지목).
163
+ *
164
+ * 좌표가 흩어져 있던 것이 구조적 원인이라 **한 자리에서 정한다.**
165
+ */
166
+ function resolveRepoRoot(sourceRoot) {
167
+ return basename(sourceRoot) === "src" ? resolve(sourceRoot, "..") : resolve(sourceRoot);
168
+ }
169
+
170
+ const repoRootDir = resolveRepoRoot(root);
171
+
156
172
  /**
157
173
  * shadcn 기본 토큰 어휘(재작성 표의 좌변·memo102 §4.1). 우리 @theme 에 없는 이름이라 클래스가 생성되지
158
174
  * 않는다 — 색이 빠진 채로 조용히 배포되는 종류의 사고라 declared 모드에서 error 다.
@@ -1100,7 +1116,7 @@ const STYLE_MODE = detectStyleMode(root);
1100
1116
  * 여기서 하는 일은 판정을 바꾸는 것이 아니라 **판정 결과를 보이게 하는 것**뿐이다.
1101
1117
  */
1102
1118
  function detectContentMode(srcDir) {
1103
- const repoRoot = resolve(srcDir, "..");
1119
+ const repoRoot = resolveRepoRoot(srcDir);
1104
1120
  let declared;
1105
1121
  let dir = resolve(srcDir);
1106
1122
  for (let i = 0; i < 12; i++) {
@@ -1221,7 +1237,7 @@ function docsSink() {
1221
1237
  * (`sections.ts` 등)도 언급하기 때문이고, 그 셋이 템플릿 형상의 서브트리다.
1222
1238
  */
1223
1239
  function checkDocCoordinates() {
1224
- const repoRoot = resolve(root, "..");
1240
+ const repoRoot = repoRootDir;
1225
1241
  const sink = docsSink();
1226
1242
 
1227
1243
  const agents = join(repoRoot, "AGENTS.md");
@@ -1319,7 +1335,10 @@ function walk(dir) {
1319
1335
  // ⚠ **관문 대가가 있다**(심의 실측): `.mjs` 를 훑으면서 `preview-runner --gate` 의 종료코드가
1320
1336
  // **0 → 1** 로 바뀐다(`[E3]` 예시 키 `oqsk_test_…` 를 오류층으로 잡는다). 실제 서빙 코퍼스는
1321
1337
  // rc=0 을 유지해 오늘의 폭발반경은 0 이지만, **발행이 남의 관문 계약을 바꾼다**는 사실은
1322
- // 여기 적어 둔다. 소비처가 파일을 예시로 두고 있다면 `zalkera-allow-…` 마커나 제외가 필요하다.
1338
+ // 여기 적어 둔다. 처방은 **면제 마커가 아니다**(설계 심의 DON'T-BUILD) 시험 픽스처는
1339
+ // 접두 뒤 **7자 이하**를 쓰면 된다. E3 잣대가 `{8,}` 이고 실키는 43자라 7자는 **구성상
1340
+ // 실키일 수 없다**. 값 규약은 구성으로 면제하고 마커는 주장으로 면제한다 — 마커는 진짜
1341
+ // 키에도 똑같이 열리므로 E3 의 오류층 자격을 스스로 철회하는 셈이다.
1323
1342
  //
1324
1343
  // ⚠ `.mjs`·`.cjs` 도 훑는다. 종전엔 빠져 있어 **그 파일에서는 규칙이 아예 안 돌았다**
1325
1344
  // (심의 관찰 — 검사기가 조용한 것이지 안전한 것이 아니다). Next 설정·서버 유틸이 그 확장자로
@@ -1721,7 +1740,7 @@ function checkContentContract() {
1721
1740
  const sink = contentSink();
1722
1741
  if (!sink) return;
1723
1742
 
1724
- const repoRoot = resolve(root, "..");
1743
+ const repoRoot = repoRootDir;
1725
1744
  const rel = (p) => relative(process.cwd(), p);
1726
1745
  const files = contentPageFiles(repoRoot);
1727
1746
 
@@ -2131,7 +2150,11 @@ function stripLiterals(code, jsx = false) {
2131
2150
  }
2132
2151
  if (c === "/" && code[i + 1] === "*") {
2133
2152
  const start = i;
2134
- i = code.indexOf("*/", i);
2153
+ // ⚠ **오프너 다음부터** 찾는다. `i` 에서 찾으면 `/*/api/…` 의 앞 두 글자(`*` + `/`)
2154
+ // 가짜 종료가 돼 주석이 즉시 닫힌 것으로 읽힌다 — 뒤따르는 진짜 코드가 주석으로 남아
2155
+ // **가드 없는 POST 에 X1 이 완전히 침묵**했다(심의 실측 · 퍼징 40,000회에서 두 사본이
2156
+ // 1,161건 갈렸고 이 수정으로 0건). 두 사본 비대칭의 유일한 원인이었다.
2157
+ i = code.indexOf("*/", i + 2);
2135
2158
  if (i < 0) i = code.length;
2136
2159
  else i += 1;
2137
2160
  blank(start, i + 1);
@@ -2534,7 +2557,7 @@ function checkCrossOriginGuards() {
2534
2557
 
2535
2558
  /** Pages Router 루트(`<src>/pages` 또는 레포 루트 `pages`). 없으면 null — 부재는 결함이 아니다. */
2536
2559
  function pagesRoot() {
2537
- for (const cand of [join(root, "pages"), join(resolve(root, ".."), "pages")]) {
2560
+ for (const cand of [join(root, "pages"), join(repoRootDir, "pages")]) {
2538
2561
  try {
2539
2562
  if (statSync(cand).isDirectory()) return cand;
2540
2563
  } catch {
@@ -2653,7 +2676,7 @@ function checkPagesRouter() {
2653
2676
  * 값은 안 본다(형태만 본다) — 검사기가 시크릿 값을 읽어 출력에 실으면 그게 또 하나의 유출이다.
2654
2677
  */
2655
2678
  function checkEnvFiles() {
2656
- const repoRoot = resolve(root, "..");
2679
+ const repoRoot = repoRootDir;
2657
2680
  let names;
2658
2681
  try {
2659
2682
  names = readdirSync(repoRoot).filter((n) => n === ".env" || n.startsWith(".env."));
@@ -2716,7 +2739,7 @@ function isStaticallyReadableConfig(text) {
2716
2739
  }
2717
2740
 
2718
2741
  function checkServingOutputContract() {
2719
- const repoRoot = resolve(root, "..");
2742
+ const repoRoot = repoRootDir;
2720
2743
  const found = NEXT_CONFIG_NAMES.map((n) => join(repoRoot, n)).filter((p) => existsSync(p));
2721
2744
  // 설정 파일이 여럿이면 어느 것이 유효한지 Next 의 해석 순서에 달렸다 — 못 가르는 자리라 스킵한다.
2722
2745
  if (found.length !== 1) return;
@@ -2782,7 +2805,7 @@ checkServingOutputContract(); // O1 — 서빙 산출물 계약(경고 전용·
2782
2805
  function checkManualCarrier() {
2783
2806
  // ⚠ **절대 경로여야 한다.** 초판이 `join(root, "..")` 상대 경로를 `createRequire` 에 넘겨 조용히
2784
2807
  // catch 로 빠졌고, 사본을 훼손해도 경고가 안 났다(변이 실측). 있는데 안 도는 검사기가 없는 것보다 나쁘다.
2785
- const projectRoot = resolve(root, "..");
2808
+ const projectRoot = repoRootDir;
2786
2809
  const at = join(projectRoot, "llms.txt");
2787
2810
  if (!existsSync(at)) return; // 없으면 스킵 — 지운 것은 자유.
2788
2811
  let carried;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zalkera/client",
3
- "version": "0.21.0",
3
+ "version": "0.21.2",
4
4
  "description": "zalkera 헤드리스 CMS 공개 API 클라이언트 (테넌트 사이트용)",
5
5
  "license": "MIT",
6
6
  "author": "Credium Co., Ltd.",