chore: initialize from frontend template 4dc033c

This commit is contained in:
DongHyeonka
2026-08-13 18:23:26 +09:00
commit 40107eec84
897 changed files with 234824 additions and 0 deletions
+441
View File
@@ -0,0 +1,441 @@
import { readFile, readdir } from "node:fs/promises";
import path from "node:path";
export const REQUIRED_RECIPE_IDS = Object.freeze([
"analytics-error-sink",
"browser-permission",
"client-workflow",
"feature-flag",
"file-transfer",
"generated-api",
"large-data-ui",
"multi-tab",
"offline-indexeddb",
"realtime",
"service-worker-pwa",
"web-worker",
] as const);
const lifecycleRecipes: ReadonlySet<string> = new Set([
"analytics-error-sink",
"browser-permission",
"client-workflow",
"file-transfer",
"generated-api",
"multi-tab",
"offline-indexeddb",
"realtime",
"service-worker-pwa",
"web-worker",
]);
type Document = Readonly<Record<string, unknown>>;
export type OptionalRecipeSourceViolation = Readonly<{
ruleId: string;
path: string;
}>;
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function recordValue(value: unknown): Record<string, unknown> {
return isRecord(value) ? value : {};
}
function recordRows(value: unknown): Record<string, unknown>[] {
return Array.isArray(value) ? value.filter(isRecord) : [];
}
function nonEmptyStrings(value: unknown): value is string[] {
return (
Array.isArray(value) &&
value.length > 0 &&
value.every(
(entry): entry is string =>
typeof entry === "string" && entry.trim().length > 0,
)
);
}
function packageVersions(value: unknown): Record<string, string> {
return Object.fromEntries(
Object.entries(recordValue(value)).filter(
(entry): entry is [string, string] => typeof entry[1] === "string",
),
);
}
export function validateRecipeCatalog(
input: unknown,
packageDocument: Document,
): string[] {
const document = recordValue(input);
const violations: string[] = [];
if (document.schemaVersion !== 1) violations.push("CATALOG_SCHEMA_VERSION");
if (document.decisionId !== "VD-10") violations.push("CATALOG_DECISION");
if (document.defaultStatus !== "NOT_INSTALLED") {
violations.push("CATALOG_DEFAULT_MUST_BE_NOT_INSTALLED");
}
if (
!Array.isArray(document.productionRuntimeDependencies) ||
document.productionRuntimeDependencies.length > 0
) {
violations.push("UNSELECTED_RUNTIME_DEPENDENCY");
}
if (!nonEmptyStrings(document.vendorPackagePatterns)) {
violations.push("VENDOR_PATTERN_CATALOG");
}
if (!Array.isArray(document.recipes)) {
return [...violations, "RECIPE_CATALOG_MISSING"];
}
const recipes = recordRows(document.recipes);
const actualIds = recipes.map((recipe) => String(recipe.id ?? "")).sort();
if (JSON.stringify(actualIds) !== JSON.stringify(REQUIRED_RECIPE_IDS)) {
violations.push("RECIPE_ID_SET");
}
if (new Set(actualIds).size !== actualIds.length) {
violations.push("RECIPE_ID_DUPLICATE");
}
for (const recipe of recipes) {
const id = typeof recipe.id === "string" ? recipe.id : "unknown";
if (recipe.status !== "RECIPE_AVAILABLE") {
violations.push(`${id}:STATUS_MUST_NOT_CLAIM_INSTALLED`);
}
for (const field of [
"trigger",
"boundary",
"port",
"fake",
"owner",
"fallback",
"serverStatePolicy",
] as const) {
const value = recipe[field];
if (typeof value !== "string" || value.trim().length === 0) {
violations.push(`${id}:MISSING_${field.toUpperCase()}`);
}
}
for (const field of [
"forbiddenWhen",
"failureKinds",
"securityPrivacy",
"removal",
] as const) {
if (!nonEmptyStrings(recipe[field])) {
violations.push(`${id}:MISSING_${field.toUpperCase()}`);
}
}
if (
typeof recipe.bundleBudgetGzipBytes !== "number" ||
!Number.isInteger(recipe.bundleBudgetGzipBytes) ||
recipe.bundleBudgetGzipBytes < 1
) {
violations.push(`${id}:INVALID_BUNDLE_BUDGET`);
}
if (recipe.owner === "frontend-platform") {
violations.push(`${id}:PROJECT_OWNER_NOT_ASSIGNED`);
}
if (lifecycleRecipes.has(id) && !nonEmptyStrings(recipe.lifecycleMethods)) {
violations.push(`${id}:CLEANUP_CONTRACT_MISSING`);
}
if (
id === "client-workflow" &&
recipe.serverStatePolicy !== "reference-only"
) {
violations.push(`${id}:SERVER_STATE_DUPLICATION_POLICY`);
}
}
const dependencies = {
...packageVersions(packageDocument.dependencies),
...packageVersions(packageDocument.devDependencies),
};
const packageScripts = packageVersions(packageDocument.scripts);
for (const recipe of recipes) {
if (recipe.referenceRuntime === undefined) continue;
const runtime = recordValue(recipe.referenceRuntime);
const id = typeof recipe.id === "string" ? recipe.id : "unknown";
if (
runtime.status !== "AVAILABLE_NOT_COMPOSED" ||
runtime.productionComposition !== false
) {
violations.push(`${id}:REFERENCE_RUNTIME_COMPOSITION`);
}
if (!nonEmptyStrings(runtime.sourceRoots)) {
violations.push(`${id}:REFERENCE_RUNTIME_SOURCE_ROOTS`);
} else if (
runtime.sourceRoots.some(
(sourceRoot) =>
!sourceRoot.startsWith("src/") ||
sourceRoot.includes("\\") ||
sourceRoot.split("/").includes(".."),
)
) {
violations.push(`${id}:REFERENCE_RUNTIME_SOURCE_BOUNDARY`);
}
if (!nonEmptyStrings(runtime.coveredCapabilities)) {
violations.push(`${id}:REFERENCE_RUNTIME_CAPABILITIES`);
}
if (!nonEmptyStrings(runtime.conformanceScripts)) {
violations.push(`${id}:REFERENCE_RUNTIME_CONFORMANCE`);
} else {
for (const script of runtime.conformanceScripts) {
if (!(script in packageScripts)) {
violations.push(`${id}:UNKNOWN_CONFORMANCE_SCRIPT:${script}`);
}
}
}
}
const vendorPatterns = Array.isArray(document.vendorPackagePatterns)
? document.vendorPackagePatterns.filter(
(entry): entry is string => typeof entry === "string",
)
: [];
for (const pattern of vendorPatterns) {
const wildcard = pattern.endsWith("*");
const prefix = pattern.replace(/\/?\*$/, "");
if (
Object.keys(dependencies).some(
(dependency) =>
dependency === prefix ||
dependency.startsWith(`${prefix}/`) ||
(wildcard && dependency.startsWith(prefix)),
)
) {
violations.push(`UNSELECTED_VENDOR_INSTALLED:${prefix}`);
}
}
return violations;
}
export async function sourceFiles(directory: string): Promise<string[]> {
let entries;
try {
entries = await readdir(directory, { withFileTypes: true });
} catch (error: unknown) {
if (
isRecord(error) &&
"code" in error &&
error.code === "ENOENT"
) {
return [];
}
throw error;
}
const groups: string[][] = await Promise.all(
entries.map((entry) => {
const target = path.join(directory, entry.name);
return entry.isDirectory()
? sourceFiles(target)
: /\.(?:[cm]?[jt]s|[jt]sx)$/.test(entry.name)
? [target]
: [];
}),
);
return groups.flat();
}
export async function scanOptionalRecipeSources(
root: string,
{ scanProductionBoundary = true }: Readonly<{
scanProductionBoundary?: boolean;
}> = {},
): Promise<OptionalRecipeSourceViolation[]> {
const violations: OptionalRecipeSourceViolation[] = [];
for (const file of await sourceFiles(root)) {
const relative = path.relative(process.cwd(), file).replaceAll("\\", "/");
const relativeToRoot = path.relative(root, file).replaceAll("\\", "/");
const content = await readFile(file, "utf8");
const imports = [
...content.matchAll(/(?:from\s*|import\s*\(\s*)["']([^"']+)["']/g),
]
.map((match) => match[1])
.filter((specifier): specifier is string => specifier !== undefined);
if (
scanProductionBoundary &&
(relativeToRoot.startsWith("src/") ||
(path.basename(path.resolve(root)) === "src" &&
!relativeToRoot.startsWith(".."))) &&
imports.some((specifier) =>
/(?:^|\/)recipes\/frontend-capabilities(?:\/|$)/.test(specifier),
)
) {
violations.push({ ruleId: "PRODUCTION_IMPORTS_RECIPE", path: relative });
}
const productionRelative =
path.basename(path.resolve(root)) === "src"
? `src/${relativeToRoot}`
: relativeToRoot;
const isCompositionSource =
/(?:^|\/)src\/bootstrap\//.test(productionRelative) ||
/(?:^|\/)src\/features\/installed-feature-(?:adapters|runtimes)\./.test(
productionRelative,
);
if (
scanProductionBoundary &&
isCompositionSource &&
(imports.some((specifier) =>
/(?:^|\/)adapters\/(?:browser-file-storage|browser-files|browser-transfer|cache-storage|storage\/(?:indexeddb|opfs))(?:\/|$)/.test(
specifier,
),
) ||
/["'][^"'\r\n]*(?:^|\/)adapters\/(?:browser-file-storage|browser-files|browser-transfer|cache-storage|storage\/(?:indexeddb|opfs))(?:\/|["'])/u.test(
content,
))
) {
violations.push({
ruleId: "REFERENCE_RUNTIME_COMPOSED_WITHOUT_SELECTION",
path: relative,
});
}
const localVendorAdapter =
relative.includes("recipes/") && relative.includes("/adapters/");
if (
!localVendorAdapter &&
imports.some((specifier) =>
/^(?:@launchdarkly\/|@sentry\/|@opentelemetry\/|@openapitools\/openapi-generator-cli$|@reduxjs\/toolkit$|@tanstack\/react-virtual$|@uppy\/|firebase(?:\/|$)|idb$|react-window$|redux(?:\/|$)|socket\.io-client$|tus-js-client$|workbox-window$|xstate$|zustand$)/.test(
specifier,
),
)
) {
violations.push({ ruleId: "VENDOR_IMPORT_OUTSIDE_ADAPTER", path: relative });
}
if (
/localStorage\s*\.\s*(?:setItem|getItem)\s*\([^)]*(?:credential|password|secret|token)/is.test(
content,
) ||
/searchParams\s*\.\s*set\s*\(\s*["'](?:credential|password|secret|token)/is.test(
content,
) ||
/(?:record|track|emit)\s*\(\s*\{[\s\S]{0,400}(?:credential|password|secret|token)\s*:/i.test(
content,
)
) {
violations.push({ ruleId: "CREDENTIAL_LEAK_PATH", path: relative });
}
if (
/(?:createStore|configureStore|create\s*\()\s*\([\s\S]{0,600}(?:apiResponse|queryData|serverState)\s*:/i.test(
content,
)
) {
violations.push({
ruleId: "CLIENT_STORE_DUPLICATES_SERVER_STATE",
path: relative,
});
}
}
return violations;
}
export async function scanProductionBundle(
distRoot: string,
): Promise<string[]> {
const violations: string[] = [];
const forbiddenRuntimeMarkers = [
"frontend-optional-recipe-must-not-reach-production",
"Browser file runtime hard limits are invalid.",
"Object URL allocation failed",
"Storage pressure policy is invalid.",
"IndexedDB runtime configuration is invalid.",
"Invalid IndexedDB schema migration.",
"OPFS runtime policy is invalid.",
"OPFS operation failed.",
"Public Cache Storage policy is invalid.",
"Public cache validation failed.",
"Presigned capability vault limit is invalid.",
"Resumable upload policy is invalid.",
"Image CDN policy registry is invalid.",
] as const;
for (const file of await sourceFiles(distRoot)) {
const content = await readFile(file, "utf8");
if (forbiddenRuntimeMarkers.some((marker) => content.includes(marker))) {
violations.push(path.relative(process.cwd(), file));
}
}
const viteManifestPath = path.join(distRoot, ".vite/manifest.json");
const emittedModuleInventoryPath = path.join(
distRoot,
".vite/module-inventory.json",
);
const moduleInventoryCandidates = [
emittedModuleInventoryPath,
...(path.resolve(distRoot) === path.resolve("dist")
? ["artifacts/quality/vite-module-inventory.json"]
: []),
];
const viteManifestExists = await readFile(viteManifestPath, "utf8")
.then(() => true)
.catch((error: unknown) => {
if (isRecord(error) && error.code === "ENOENT") return false;
throw error;
});
if (!viteManifestExists) return [...new Set(violations)];
let inventory: unknown;
let moduleInventoryPath = emittedModuleInventoryPath;
for (const candidate of moduleInventoryCandidates) {
try {
inventory = JSON.parse(await readFile(candidate, "utf8"));
moduleInventoryPath = candidate;
break;
} catch {
// A generated build may move the inventory out of the deploy directory.
}
}
if (inventory === undefined) {
violations.push(
path.relative(process.cwd(), moduleInventoryPath),
);
return [...new Set(violations)];
}
const inventoryDocument = recordValue(inventory);
const chunks = recordRows(inventoryDocument.chunks);
if (
inventoryDocument.schemaVersion !== 1 ||
!Array.isArray(inventoryDocument.chunks) ||
chunks.length !== inventoryDocument.chunks.length
) {
violations.push(path.relative(process.cwd(), moduleInventoryPath));
return [...new Set(violations)];
}
const forbiddenSourcePrefixes = [
"src/application/ports/browser-file-storage/",
"src/application/ports/browser-transfer/",
"src/adapters/browser-file-storage/",
"src/adapters/browser-files/",
"src/adapters/browser-transfer/",
"src/adapters/cache-storage/",
"src/adapters/storage/indexeddb/",
"src/adapters/storage/opfs/",
] as const;
for (const chunk of chunks) {
if (
typeof chunk.fileName !== "string" ||
!Array.isArray(chunk.modules) ||
chunk.modules.some((moduleId) => typeof moduleId !== "string")
) {
violations.push(path.relative(process.cwd(), moduleInventoryPath));
continue;
}
for (const moduleId of chunk.modules as string[]) {
if (
forbiddenSourcePrefixes.some((prefix) =>
moduleId.startsWith(prefix),
)
) {
violations.push(`${chunk.fileName}:${moduleId}`);
}
}
}
return [...new Set(violations)];
}