fix: harden frontend dependency and env hygiene
This commit is contained in:
@@ -13,6 +13,10 @@ dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
# Local runtime configuration
|
||||
.env*
|
||||
!.env.example
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
|
||||
Generated
+4
-4
@@ -18,7 +18,7 @@
|
||||
"react-dom": "19.2.8",
|
||||
"react-hook-form": "7.85.0",
|
||||
"react-i18next": "16.3.5",
|
||||
"react-router": "7.9.6",
|
||||
"react-router": "7.18.2",
|
||||
"zod": "3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -5816,9 +5816,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "7.9.6",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.6.tgz",
|
||||
"integrity": "sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==",
|
||||
"version": "7.18.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.2.tgz",
|
||||
"integrity": "sha512-aUVMjFm3GAPTTZL7oYr5E7ETiqfQCHRLH+B+5afnICvf0r7kkK4eR6SMuwbSTJw/7t+12khT/Kahij49fqOCIg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cookie": "^1.0.1",
|
||||
|
||||
+3
-2
@@ -17,9 +17,10 @@
|
||||
"openapi:generate": "openapi-typescript src/shared/api/spec/openapi.json -o src/shared/api/generated/schema.d.ts",
|
||||
"openapi:sync": "node scripts/openapi-sync.mjs",
|
||||
"openapi:check": "node scripts/openapi-check.mjs",
|
||||
"hygiene:check": "node scripts/repository-hygiene-check.mjs",
|
||||
"knip": "knip",
|
||||
"deps": "depcruise src --config dependency-cruiser.cjs --output-type err-long",
|
||||
"verify": "npm run openapi:check && npm run typecheck && npm run lint && npm run test:run && npm run test:coverage && npm run knip && npm run deps && npm run build",
|
||||
"verify": "npm run openapi:check && npm run hygiene:check && npm run typecheck && npm run lint && npm run test:run && npm run test:coverage && npm run knip && npm run deps && npm run build",
|
||||
"prepare": "husky",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
@@ -37,7 +38,7 @@
|
||||
"react-dom": "19.2.8",
|
||||
"react-hook-form": "7.85.0",
|
||||
"react-i18next": "16.3.5",
|
||||
"react-router": "7.9.6",
|
||||
"react-router": "7.18.2",
|
||||
"zod": "3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
|
||||
function git(args) {
|
||||
return execFileSync("git", args, { cwd: root, encoding: "utf8" }).trim();
|
||||
}
|
||||
|
||||
function isIgnored(file) {
|
||||
try {
|
||||
execFileSync("git", ["check-ignore", "--no-index", "-q", file], {
|
||||
cwd: root,
|
||||
stdio: "ignore",
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error.status === 1) return false;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function assert(condition, message) {
|
||||
if (!condition) throw new Error(message);
|
||||
}
|
||||
|
||||
const trackedEnvironmentFiles = git(["ls-files", "--", ".env", ".env.*"])
|
||||
.split("\n")
|
||||
.filter(Boolean)
|
||||
.sort();
|
||||
|
||||
assert(
|
||||
JSON.stringify(trackedEnvironmentFiles) === JSON.stringify([".env.example"]),
|
||||
`Only .env.example may be tracked; found: ${trackedEnvironmentFiles.join(", ") || "none"}`,
|
||||
);
|
||||
|
||||
for (const file of [".env", ".env.local", ".env.development", ".env.test"]) {
|
||||
assert(isIgnored(file), `Local environment file must be ignored: ${file}`);
|
||||
}
|
||||
|
||||
assert(!isIgnored(".env.example"), ".env.example must remain versionable");
|
||||
|
||||
console.log("Frontend repository hygiene verified");
|
||||
Reference in New Issue
Block a user