UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

69 lines 2.97 kB
import { STANDARD_ERROR_RESPONSE_SCHEMA } from "./types.js"; function isContractErrorDefinition(value) { return (typeof value === "object" && value !== null && typeof value.code === "string" && typeof value.status === "number" && typeof value.message === "string"); } /** * Extract catalog error definitions declared in contract metadata. */ export function catalogErrorsFromMeta(metadata) { const errors = metadata.errors; if (typeof errors !== "object" || errors === null) return {}; const catalog = {}; for (const [key, definition] of Object.entries(errors)) { if (isContractErrorDefinition(definition)) { catalog[key] = definition; } } return catalog; } /** * Convert catalog error definitions into standard envelope response schemas. */ export function responsesFromErrors(errors) { const responses = {}; for (const error of Object.values(errors)) { responses[error.status] = STANDARD_ERROR_RESPONSE_SCHEMA; } return responses; } /** * Merge catalog errors already declared in metadata with new declarations. * * Later declarations win when the same catalog key is declared twice. */ export function mergeCatalogErrors(metadata, errorDefs) { return { ...catalogErrorsFromMeta(metadata), ...errorDefs }; } function catalogErrorStatuses(metadata) { return new Set(Object.values(catalogErrorsFromMeta(metadata)).map((error) => String(error.status))); } /** * Reject `.errors()` statuses that collide with custom response schemas. * * Statuses declared by earlier `.errors()` calls are allowed: catalog errors * share the standard error envelope, so multiple codes can map to one status. */ export function assertErrorsAvoidCustomResponseStatuses(metadata, responses, nextErrorResponses) { const existingErrorStatuses = catalogErrorStatuses(metadata); const customStatuses = new Set(Object.keys(responses).filter((status) => !existingErrorStatuses.has(status))); const conflicts = Object.keys(nextErrorResponses).filter((status) => customStatuses.has(status)); if (conflicts.length) { throw new Error(`.errors() cannot declare status ${conflicts.join(", ")} because a response schema for that status already exists. Use .responses() without .errors() when you need a custom error response body.`); } } /** * Reject `.responses()` statuses already declared by catalog errors. */ export function assertResponsesAvoidCatalogErrorStatuses(metadata, next) { const errorStatuses = catalogErrorStatuses(metadata); const conflicts = Object.keys(next).filter((status) => errorStatuses.has(status)); if (conflicts.length) { throw new Error(`.responses() cannot declare status ${conflicts.join(", ")} because that status is already declared by .errors(). Use .responses() without .errors() when you need a custom error response body.`); } } //# sourceMappingURL=catalog-errors.js.map