import console from "node:console"; import { existsSync, readFileSync, readdirSync } from "node:fs"; import { dirname, join, resolve } from "node:path"; import process from "node:process"; import { fileURLToPath } from "node:url"; import { spawnSync } from "node:child_process"; const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); let passed = 0; let failed = 0; const failures = []; function check(name, condition, detail = "") { if (condition) { passed++; console.log(` ok ${name}`); return; } failed++; failures.push(detail ? `${name}: ${detail}` : name); console.error(` FAIL ${name}${detail ? ` — ${detail}` : ""}`); } function text(path) { return readFileSync(join(root, path), "utf8"); } function has(path, value) { const source = text(path); return typeof value === "string" ? source.includes(value) : value.test(source); } const rootManifest = JSON.parse(text("package.json")); const releaseVersion = rootManifest.version; check( "repository governance documents exist", ["LICENSE", "SECURITY.md", "CONTRIBUTING.md", "CHANGELOG.md", "CODE_OF_CONDUCT.md"].every( (file) => existsSync(join(root, file)), ), ); const packageManifests = readdirSync(join(root, "packages"), { withFileTypes: true }) .filter( (entry) => entry.isDirectory() && existsSync(join(root, "packages", entry.name, "package.json")), ) .map((entry) => JSON.parse(text(`packages/${entry.name}/package.json`))); const workspaceManifests = ["packages", "examples", "services"].flatMap((directory) => readdirSync(join(root, directory), { withFileTypes: true }) .filter( (entry) => entry.isDirectory() && existsSync(join(root, directory, entry.name, "package.json")), ) .map((entry) => JSON.parse(text(`${directory}/${entry.name}/package.json`))), ); check( "package manifests avoid floating latest dependency ranges", ![rootManifest, ...workspaceManifests].some((manifest) => [manifest.dependencies, manifest.devDependencies, manifest.peerDependencies].some((group) => Object.values(group ?? {}).includes("latest"), ), ), ); check("root version is a 0.8 release", /^0\.8\.\d+$/.test(releaseVersion)); check( `all framework packages use ${releaseVersion}`, packageManifests.every((manifest) => manifest.version === releaseVersion), ); check( "standalone realtime package exists", existsSync(join(root, "packages/realtime/src/index.ts")) && existsSync(join(root, "packages/realtime/components/RealtimeRoom.wrn")), ); check( "auth provides helper and UI block kits", existsSync(join(root, "packages/auth/src/helpers.ts")) && existsSync(join(root, "packages/auth/components/AuthShell.wrn")) && has("packages/auth/package.json", '"@wrnexus/ui": "workspace:*"'), ); check( "captcha provides helper and UI wrapper kits", existsSync(join(root, "packages/captcha/src/helpers.ts")) && existsSync(join(root, "packages/captcha/components/CaptchaField.wrn")), ); check( "database repository helpers exist", has("packages/db/src/helpers.ts", "createRepository") && has("packages/db/src/helpers.ts", "retryTransaction"), ); check( "database repositories use dialect-aware placeholders", has("packages/db/src/helpers.ts", 'dialect === "postgres" ? `$${index}` : "?"') && has("packages/db/test/helpers.test.ts", "VALUES ($1)"), ); check( "encrypted HTTP envelope is context and replay bound", has("packages/encryption/src/http.ts", "WRN-ENCRYPTION-HTTP-REPLAY") && has("packages/encryption/src/http.ts", "payload.path !== normalizePath"), ); check( "encrypted responses are request-id bound and application errors propagate", has("packages/encryption/src/http.ts", "expectedRequestId: requestId") && has("packages/encryption/src/http.ts", "const response = await next();"), ); check( "encryption documentation preserves HTTPS boundary", has("packages/encryption/README.md", /TLS|HTTPS/) && has("packages/encryption/README.md", /browser|end user/i), ); check( "JWT access, refresh, scope, cookie, and pair helpers exist", [ "createAccessToken", "createRefreshToken", "requireScopes", "jwtCookie", "readJwtCookie", "createTokenPair", ].every((name) => has("packages/jwt/src/helpers.ts", name)), ); check( "i18n supports nested locales and quality negotiation", has("packages/i18n/src/index.ts", "localeFiles") && has("packages/i18n/src/index.ts", "parseAcceptLanguage"), ); check( "i18n safely resolves namespace collisions and wildcard language ranges", has("packages/i18n/src/index.ts", 'tag?.trim() === "*"') && has("packages/i18n/test/package-kit.test.ts", "primitive namespace collisions"), ); check( "i18n runtime data is injected into rendered documents", has("packages/dev-server/src/runtime.ts", "renderI18nData(deps.i18n, language)") && has("packages/dev-server/src/runtime.ts", "deps.i18n.cookie.name"), ); check( "image package provides picture, loaders, placeholder, and preload helpers", ["createPicture", "createCdnImageLoader", "createBlurPlaceholder", "imagePreload"].every((name) => has("packages/image/src/index.ts", name), ), ); check( "image helpers validate finite dimensions and preserve URL fragments", has("packages/image/src/index.ts", "Image width bounds must be finite") && has("packages/image/test/package-kit.test.ts", "URL fragments"), ); check( "realtime messages are size, room, type, and payload bounded", has("packages/realtime/src/messages.ts", "maxBytes") && has("packages/realtime/src/messages.ts", "Unsafe realtime payload key"), ); check( "auth shell uses statically discoverable Tailwind width classes", !has("packages/auth/components/AuthShell.wrn", "max-w-{maxWidth}") && has("packages/auth/components/AuthShell.wrn", "class:max-w-md"), ); check( "uploader package provides UI blocks and helpers", existsSync(join(root, "packages/uploader/components/UploadDropzone.wrn")) && existsSync(join(root, "packages/uploader/src/helpers.ts")), ); check( "validation package provides UI blocks and helpers", existsSync(join(root, "packages/validation/components/ValidationSummary.wrn")) && existsSync(join(root, "packages/validation/src/helpers.ts")), ); check( "validation schemas infer helper output types", has("packages/validation/src/index.ts", "export type InferSchema") && has("packages/validation/src/helpers.ts", "schema: ObjectSchema") && has("packages/validation/test/helpers.test.ts", "const email: string = value.email"), ); check( "validation oneOf preserves literal union types", has("packages/validation/src/index.ts", "class StringSchema"), ); check("0.8 migration exists", has("packages/cli/src/update.ts", 'id: "0.8.0-01-package-kits"')); check( "package kit audit exists", existsSync(join(root, "scripts/audit-package-kits.mjs")) && rootManifest.scripts?.["audit:packages"] === "node scripts/audit-package-kits.mjs", ); check( "audit validators are read-only and reports use explicit generators", rootManifest.scripts?.["security:framework"] === "node scripts/security-performance-audit.mjs" && rootManifest.scripts?.["generate:security-report"] === "node scripts/security-performance-audit.mjs --write" && rootManifest.scripts?.["generate:package-audit"] === "node scripts/audit-package-kits.mjs --write" && has("scripts/security-performance-audit.mjs", 'process.argv.includes("--write")') && has("scripts/audit-package-kits.mjs", 'process.argv.includes("--write")'), ); const publicApi = spawnSync(process.execPath, ["scripts/check-public-api.mjs"], { cwd: root, encoding: "utf8", }); if (publicApi.stdout) process.stdout.write(publicApi.stdout); if (publicApi.stderr) process.stderr.write(publicApi.stderr); check( "public package exports match the reviewed API baseline", publicApi.status === 0 && existsSync(join(root, "docs/public-api-0.8.json")), ); const audit = spawnSync(process.execPath, ["scripts/audit-package-kits.mjs"], { cwd: root, encoding: "utf8", }); if (audit.stdout) process.stdout.write(audit.stdout); if (audit.stderr) process.stderr.write(audit.stderr); check("all package kits pass the executable audit", audit.status === 0); const runtimeProbe = spawnSync( process.execPath, ["--experimental-transform-types", "scripts/test-package-kits.mjs"], { cwd: root, encoding: "utf8" }, ); if (runtimeProbe.stdout) process.stdout.write(runtimeProbe.stdout); if (runtimeProbe.stderr) process.stderr.write(runtimeProbe.stderr); check("package helper runtime probes pass", runtimeProbe.status === 0); check( "package helper APIs have dedicated tests", [ "packages/encryption/test/http.test.ts", "packages/jwt/test/helpers.test.ts", "packages/db/test/helpers.test.ts", "packages/i18n/test/package-kit.test.ts", "packages/image/test/package-kit.test.ts", "packages/captcha/test/helpers.test.ts", "packages/uploader/test/helpers.test.ts", "packages/validation/test/helpers.test.ts", "packages/realtime/test/realtime.test.ts", "packages/auth/test/package-components.test.ts", ].every((path) => existsSync(join(root, path))), ); console.log(`\n${passed} passed`); console.log(`${failed} failed`); if (failed) { console.error("\nFailures:"); for (const value of failures) console.error(`- ${value}`); process.exitCode = 1; }