refactor: 리펙토링

This commit is contained in:
DongHyeonka
2026-08-01 19:39:59 +09:00
parent 9c959ea2a5
commit c6da03369c
171 changed files with 20329 additions and 782 deletions
+82
View File
@@ -0,0 +1,82 @@
export type GateStepExpectation =
| Readonly<{ kind: "pass" }>
| Readonly<{
kind: "fail";
expectedExitCode: number;
expectedDiagnosticId: string;
}>;
export type GateProcessResult = Readonly<{
status: number | null;
signal: string | null;
stdout: string;
stderr: string;
error?: Readonly<{ code?: string }>;
}>;
export type GateStepClassification =
| Readonly<{
kind: "EXPECTED_PASS" | "EXPECTED_FAILURE";
expectationMet: true;
}>
| Readonly<{
kind: "UNEXPECTED_EXIT";
expectationMet: false;
}>
| Readonly<{
kind: "UNEXPECTED_DIAGNOSTIC";
expectationMet: false;
}>
| Readonly<{
kind: "INFRASTRUCTURE_FAILURE";
expectationMet: false;
detail: string;
}>;
/** A negative fixture passes only with its registered exit and diagnostic. */
export function classifyGateStepResult(
expectation: GateStepExpectation,
result: GateProcessResult,
): GateStepClassification {
const errorCode = result.error?.code;
const spawnFailed = result.error !== undefined;
if (spawnFailed || result.signal || result.status === null) {
return Object.freeze({
kind: "INFRASTRUCTURE_FAILURE" as const,
expectationMet: false as const,
detail:
errorCode ??
result.signal ??
(spawnFailed ? "SPAWN_ERROR" : "NO_EXIT_STATUS"),
});
}
if (expectation.kind === "pass" && result.status === 0) {
return Object.freeze({
kind: "EXPECTED_PASS" as const,
expectationMet: true as const,
});
}
if (expectation.kind === "fail") {
if (result.status !== expectation.expectedExitCode) {
return Object.freeze({
kind: "UNEXPECTED_EXIT" as const,
expectationMet: false as const,
});
}
const diagnosticOutput = `${result.stdout}\n${result.stderr}`;
if (!diagnosticOutput.includes(expectation.expectedDiagnosticId)) {
return Object.freeze({
kind: "UNEXPECTED_DIAGNOSTIC" as const,
expectationMet: false as const,
});
}
return Object.freeze({
kind: "EXPECTED_FAILURE" as const,
expectationMet: true as const,
});
}
return Object.freeze({
kind: "UNEXPECTED_EXIT" as const,
expectationMet: false as const,
});
}
+24
View File
@@ -0,0 +1,24 @@
import { z } from "zod";
/**
* Compile a checked-in JSON Schema and assert a concrete artifact against it.
* Conversion failures are fatal too: an unsupported or malformed schema must
* not silently turn a release schema into documentation-only metadata.
*/
export function assertMatchesJsonSchema(
schemaDocument: unknown,
value: unknown,
label: string,
): void {
try {
const schema = z.fromJSONSchema(schemaDocument as never);
const result = schema.safeParse(value);
if (!result.success) {
throw new TypeError(z.prettifyError(result.error));
}
} catch (error) {
throw new TypeError(`${label} does not satisfy its checked-in JSON Schema.`, {
cause: error,
});
}
}
+101
View File
@@ -0,0 +1,101 @@
import type {
InstalledServiceWorkerSelection,
ServiceWorkerHandlerId,
StaticAssetManifestV1,
} from "../../src/contracts/service-worker.ts";
const DIGEST = /^sha256:[0-9a-f]{64}$/u;
export type ServiceWorkerBuildInput = Readonly<{
assets: StaticAssetManifestV1;
handlers: readonly ServiceWorkerHandlerId[];
contractSetDigest: string;
releaseManifestUrl: string;
}>;
/**
* ACTIVE worker compilation is a release-integrity boundary. Missing generated
* modules, stale identities and placeholder digests are fatal build defects;
* they must never be converted into a worker that merely degrades at runtime.
*/
export function resolveServiceWorkerBuildInput(input: Readonly<{
selection: InstalledServiceWorkerSelection | null;
assets: unknown;
contractSet: unknown;
runtimeConfig: unknown;
buildId: string;
releaseId: string;
}>): ServiceWorkerBuildInput {
if (input.selection?.mode !== "ACTIVE") {
throw new TypeError(
"Service Worker build requires an ACTIVE static selection.",
);
}
if (!Array.isArray(input.selection.handlers)) {
throw new TypeError("Service Worker handlers must be an array.");
}
const handlers = new Set<ServiceWorkerHandlerId>();
for (const handler of input.selection.handlers) {
if (
handler !== "PWA_STATIC_ASSETS" &&
handler !== "OFFLINE_SYNC_WAKEUP" &&
handler !== "WEB_PUSH"
) {
throw new TypeError(`Unknown Service Worker handler: ${String(handler)}.`);
}
if (handlers.has(handler)) {
throw new TypeError(`Duplicate Service Worker handler: ${handler}.`);
}
handlers.add(handler);
}
if (handlers.has("WEB_PUSH")) {
throw new TypeError(
"WEB_PUSH requires an installed product-owned worker contribution.",
);
}
const assets = parseAssets(input.assets);
if (assets.buildId !== input.buildId || assets.releaseId !== input.releaseId) {
throw new TypeError("Generated Service Worker asset identity is stale.");
}
const contractSet = record(input.contractSet);
const contractSetDigest = contractSet?.setDigest;
if (typeof contractSetDigest !== "string" || !DIGEST.test(contractSetDigest)) {
throw new TypeError("Generated contract set digest is invalid.");
}
const runtimeConfig = record(input.runtimeConfig);
const releaseManifestUrl = runtimeConfig?.RELEASE_MANIFEST_URL;
if (
typeof releaseManifestUrl !== "string" ||
releaseManifestUrl.length === 0 ||
releaseManifestUrl.length > 2_048
) {
throw new TypeError("Runtime release manifest URL is invalid.");
}
return Object.freeze({
assets,
handlers: Object.freeze([...handlers]),
contractSetDigest,
releaseManifestUrl,
});
}
function parseAssets(value: unknown): StaticAssetManifestV1 {
const candidate = record(value);
if (
candidate?.schemaVersion !== 1 ||
typeof candidate.buildId !== "string" ||
typeof candidate.releaseId !== "string" ||
typeof candidate.setDigest !== "string" ||
!DIGEST.test(candidate.setDigest) ||
!Array.isArray(candidate.assets)
) {
throw new TypeError("Generated Service Worker asset manifest is invalid.");
}
return candidate as unknown as StaticAssetManifestV1;
}
function record(value: unknown): Record<string, unknown> | null {
return value && typeof value === "object" && !Array.isArray(value)
? (value as Record<string, unknown>)
: null;
}