@zalkera/client 0.21.1 → 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");
@@ -1724,7 +1740,7 @@ function checkContentContract() {
1724
1740
  const sink = contentSink();
1725
1741
  if (!sink) return;
1726
1742
 
1727
- const repoRoot = resolve(root, "..");
1743
+ const repoRoot = repoRootDir;
1728
1744
  const rel = (p) => relative(process.cwd(), p);
1729
1745
  const files = contentPageFiles(repoRoot);
1730
1746
 
@@ -2134,7 +2150,11 @@ function stripLiterals(code, jsx = false) {
2134
2150
  }
2135
2151
  if (c === "/" && code[i + 1] === "*") {
2136
2152
  const start = i;
2137
- i = code.indexOf("*/", i);
2153
+ // ⚠ **오프너 다음부터** 찾는다. `i` 에서 찾으면 `/*/api/…` 의 앞 두 글자(`*` + `/`)
2154
+ // 가짜 종료가 돼 주석이 즉시 닫힌 것으로 읽힌다 — 뒤따르는 진짜 코드가 주석으로 남아
2155
+ // **가드 없는 POST 에 X1 이 완전히 침묵**했다(심의 실측 · 퍼징 40,000회에서 두 사본이
2156
+ // 1,161건 갈렸고 이 수정으로 0건). 두 사본 비대칭의 유일한 원인이었다.
2157
+ i = code.indexOf("*/", i + 2);
2138
2158
  if (i < 0) i = code.length;
2139
2159
  else i += 1;
2140
2160
  blank(start, i + 1);
@@ -2537,7 +2557,7 @@ function checkCrossOriginGuards() {
2537
2557
 
2538
2558
  /** Pages Router 루트(`<src>/pages` 또는 레포 루트 `pages`). 없으면 null — 부재는 결함이 아니다. */
2539
2559
  function pagesRoot() {
2540
- for (const cand of [join(root, "pages"), join(resolve(root, ".."), "pages")]) {
2560
+ for (const cand of [join(root, "pages"), join(repoRootDir, "pages")]) {
2541
2561
  try {
2542
2562
  if (statSync(cand).isDirectory()) return cand;
2543
2563
  } catch {
@@ -2656,7 +2676,7 @@ function checkPagesRouter() {
2656
2676
  * 값은 안 본다(형태만 본다) — 검사기가 시크릿 값을 읽어 출력에 실으면 그게 또 하나의 유출이다.
2657
2677
  */
2658
2678
  function checkEnvFiles() {
2659
- const repoRoot = resolve(root, "..");
2679
+ const repoRoot = repoRootDir;
2660
2680
  let names;
2661
2681
  try {
2662
2682
  names = readdirSync(repoRoot).filter((n) => n === ".env" || n.startsWith(".env."));
@@ -2719,7 +2739,7 @@ function isStaticallyReadableConfig(text) {
2719
2739
  }
2720
2740
 
2721
2741
  function checkServingOutputContract() {
2722
- const repoRoot = resolve(root, "..");
2742
+ const repoRoot = repoRootDir;
2723
2743
  const found = NEXT_CONFIG_NAMES.map((n) => join(repoRoot, n)).filter((p) => existsSync(p));
2724
2744
  // 설정 파일이 여럿이면 어느 것이 유효한지 Next 의 해석 순서에 달렸다 — 못 가르는 자리라 스킵한다.
2725
2745
  if (found.length !== 1) return;
@@ -2785,7 +2805,7 @@ checkServingOutputContract(); // O1 — 서빙 산출물 계약(경고 전용·
2785
2805
  function checkManualCarrier() {
2786
2806
  // ⚠ **절대 경로여야 한다.** 초판이 `join(root, "..")` 상대 경로를 `createRequire` 에 넘겨 조용히
2787
2807
  // catch 로 빠졌고, 사본을 훼손해도 경고가 안 났다(변이 실측). 있는데 안 도는 검사기가 없는 것보다 나쁘다.
2788
- const projectRoot = resolve(root, "..");
2808
+ const projectRoot = repoRootDir;
2789
2809
  const at = join(projectRoot, "llms.txt");
2790
2810
  if (!existsSync(at)) return; // 없으면 스킵 — 지운 것은 자유.
2791
2811
  let carried;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zalkera/client",
3
- "version": "0.21.1",
3
+ "version": "0.21.2",
4
4
  "description": "zalkera 헤드리스 CMS 공개 API 클라이언트 (테넌트 사이트용)",
5
5
  "license": "MIT",
6
6
  "author": "Credium Co., Ltd.",