@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.
- package/bin/validate-storefront.mjs +28 -8
- package/package.json +1 -1
|
@@ -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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
2808
|
+
const projectRoot = repoRootDir;
|
|
2789
2809
|
const at = join(projectRoot, "llms.txt");
|
|
2790
2810
|
if (!existsSync(at)) return; // 없으면 스킵 — 지운 것은 자유.
|
|
2791
2811
|
let carried;
|