@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.
- package/bin/validate-storefront.mjs +32 -9
- 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");
|
|
@@ -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
|
-
// 여기 적어 둔다.
|
|
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 =
|
|
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
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
2808
|
+
const projectRoot = repoRootDir;
|
|
2786
2809
|
const at = join(projectRoot, "llms.txt");
|
|
2787
2810
|
if (!existsSync(at)) return; // 없으면 스킵 — 지운 것은 자유.
|
|
2788
2811
|
let carried;
|