import { z } from "zod"; import type { CommandEffectDescriptor, InstalledContractContribution, InstalledHttpContract, RuntimeValidator, } from "../../src/contracts/external-contract-runtime.ts"; function zodValidator( schemaId: string, schema: z.ZodType, ): RuntimeValidator { return Object.freeze({ schemaId, safeParse(value: unknown) { const result = schema.safeParse(value); if (result.success) { return Object.freeze({ success: true as const, data: result.data }); } return Object.freeze({ success: false as const, issues: Object.freeze( result.error.issues.map((issue) => Object.freeze({ path: Object.freeze( issue.path.map((segment) => typeof segment === "number" ? segment : String(segment), ), ), code: String(issue.code), }), ), ), }); }, }); } const entitySchema = z .object({ id: z.string().min(1), name: z.string().min(1), }) .strip(); const problemSchema = z .object({ type: z.string().min(1), title: z.string().min(1), status: z.int().min(100).max(599), }) .strip(); type TestProblem = z.output; const problemValidator = zodValidator("TestProblem", problemSchema); const readPolicy = Object.freeze({ policyId: "TEST_READ_V1", requestByteLimit: 0, responseByteLimit: 32_768, totalDeadlineMs: 10_000, retryBudget: 2 as const, authProfileId: "ANONYMOUS", diagnosticsOperation: "test.read", }); export const TEST_LIST_HTTP_CONTRACT: InstalledHttpContract< Readonly<{ limit: number }>, readonly z.output[], TestProblem > = Object.freeze({ contract: Object.freeze({ operationId: "TEST_LIST_ENTITIES", method: "GET" as const, pathTemplate: "/api/test-entities", inputValidator: zodValidator( "TestEntityListQuery", z .object({ limit: z.coerce.number().int().min(1).max(100).default(20), }) .strict(), ), outputValidator: zodValidator( "TestEntityListPayload", z.array(entitySchema).max(100), ), problemValidator, acceptedStatuses: Object.freeze([200]), emptyBodyStatuses: Object.freeze([]), retrySemantics: "SAFE" as const, requestBody: "NONE" as const, responseBody: "REQUIRED_JSON" as const, commandRecovery: null, commandEffect: null, projectRequest(input: Readonly<{ limit: number }>) { return Object.freeze({ pathValues: Object.freeze({}), queryEntries: Object.freeze([ Object.freeze(["limit", String(input.limit)] as const), ]), body: null, }); }, }), frontend: readPolicy, }); export const TEST_DETAIL_HTTP_CONTRACT: InstalledHttpContract< Readonly<{ entityId: string }>, z.output, TestProblem > = Object.freeze({ contract: Object.freeze({ operationId: "TEST_GET_ENTITY", method: "GET" as const, pathTemplate: "/api/test-entities/{entityId}", inputValidator: zodValidator( "TestEntityParams", z.object({ entityId: z.string().min(1) }).strict(), ), outputValidator: zodValidator("TestEntityPayload", entitySchema), problemValidator, acceptedStatuses: Object.freeze([200]), emptyBodyStatuses: Object.freeze([]), retrySemantics: "SAFE" as const, requestBody: "NONE" as const, responseBody: "REQUIRED_JSON" as const, commandRecovery: null, commandEffect: null, projectRequest(input: Readonly<{ entityId: string }>) { return Object.freeze({ pathValues: Object.freeze({ entityId: input.entityId }), queryEntries: Object.freeze([]), body: null, }); }, }), frontend: Object.freeze({ ...readPolicy, policyId: "TEST_DETAIL_V1", diagnosticsOperation: "test.detail", }), }); const commandEffect: CommandEffectDescriptor = Object.freeze({ successEffect: "APPLIED_CONFIRMED" as const, classifyProblem({ status, }: Readonly<{ status: number; problem: TestProblem }>) { return status === 400 ? "NOT_APPLIED" : "MAYBE_APPLIED"; }, }); export const TEST_CREATE_HTTP_CONTRACT: InstalledHttpContract< Readonly<{ name: string }>, z.output, TestProblem > = Object.freeze({ contract: Object.freeze({ operationId: "TEST_CREATE_ENTITY", method: "POST" as const, pathTemplate: "/api/test-entities", inputValidator: zodValidator( "TestCreateEntityCommand", z.object({ name: z.string().trim().min(1) }).strict(), ), outputValidator: zodValidator("TestEntityPayload", entitySchema), problemValidator, acceptedStatuses: Object.freeze([201]), emptyBodyStatuses: Object.freeze([]), retrySemantics: "KEYED" as const, requestBody: "JSON" as const, responseBody: "REQUIRED_JSON" as const, commandRecovery: Object.freeze({ mode: "IDEMPOTENCY_REPLAY" as const, operationIdentityField: "idempotencyKey", }), commandEffect, projectRequest(input: Readonly<{ name: string }>) { return Object.freeze({ pathValues: Object.freeze({}), queryEntries: Object.freeze([]), body: Object.freeze({ ...input }), }); }, }), frontend: Object.freeze({ policyId: "TEST_CREATE_V1", requestByteLimit: 32_768, responseByteLimit: 32_768, totalDeadlineMs: 10_000, retryBudget: 0 as const, authProfileId: "ANONYMOUS", diagnosticsOperation: "test.create", }), }); export const TEST_CONTRACT_CONTRIBUTION: InstalledContractContribution = Object.freeze({ contributionId: "test-http-v1", featureId: "test-feature", source: Object.freeze({ kind: "EXTERNAL_PACKAGE" as const, package: Object.freeze({ packageId: "@test/contracts", version: "1.0.0", digest: `sha256:${"a".repeat(64)}`, runtimeProtocolVersion: 1 as const, sourceRevision: "abcdef1", }), }), http: Object.freeze([ TEST_LIST_HTTP_CONTRACT, TEST_DETAIL_HTTP_CONTRACT, TEST_CREATE_HTTP_CONTRACT, ]) as readonly InstalledHttpContract[], events: Object.freeze([]), });