@lokalise/api-contracts
Version:
103 lines • 3.83 kB
JavaScript
import { z } from 'zod/v4';
import { SUCCESSFUL_HTTP_STATUS_CODES } from "../HttpStatusCodes.js";
import { ContractNoBody } from "./constants.js";
import { isAnyOfResponses, isBlobResponse, isNoBodyResponse, isSseResponse, isTextResponse, } from "./contractResponse.js";
export const defineApiContract = (contract) => contract;
export const mapApiContractToPath = (routeConfig) => {
if (!routeConfig.requestPathParamsSchema) {
return routeConfig.pathResolver(undefined);
}
const resolverParams = Object.keys(routeConfig.requestPathParamsSchema.shape).reduce((acc, key) => {
acc[key] = `:${key}`;
return acc;
}, {});
return routeConfig.pathResolver(resolverParams);
};
export const describeApiContract = (routeConfig) => {
return `${routeConfig.method.toUpperCase()} ${mapApiContractToPath(routeConfig)}`;
};
export const getSseSchemaByEventName = (routeConfig) => {
const result = {};
for (const value of Object.values(routeConfig.responsesByStatusCode)) {
if (isSseResponse(value)) {
Object.assign(result, value.schemaByEventName);
}
else if (isAnyOfResponses(value)) {
for (const response of value.responses) {
if (isSseResponse(response)) {
Object.assign(result, response.schemaByEventName);
}
}
}
}
return Object.keys(result).length > 0 ? result : null;
};
export const hasAnySuccessSseResponse = (apiContract) => {
for (const code of [...SUCCESSFUL_HTTP_STATUS_CODES, '2xx', 'default']) {
const value = apiContract.responsesByStatusCode[code];
if (!value) {
continue;
}
if (isSseResponse(value)) {
return true;
}
else if (isAnyOfResponses(value)) {
for (const response of value.responses) {
if (isSseResponse(response)) {
return true;
}
}
}
}
return false;
};
/** @deprecated No known consumers — will be removed in a future release. */
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: it is acceptable
export const getSuccessResponseSchema = (routeConfig) => {
const schemas = [];
let hasDirectNonJsonEntry = false;
for (const code of SUCCESSFUL_HTTP_STATUS_CODES) {
const value = routeConfig.responsesByStatusCode[code];
if (!value) {
continue;
}
if (isAnyOfResponses(value)) {
for (const response of value.responses) {
if (!isSseResponse(response) && !isTextResponse(response) && !isBlobResponse(response)) {
schemas.push(response);
}
}
}
else if (value === ContractNoBody ||
isNoBodyResponse(value) ||
isSseResponse(value) ||
isTextResponse(value) ||
isBlobResponse(value)) {
hasDirectNonJsonEntry = true;
}
else {
schemas.push(value);
}
}
if (schemas.length > 1) {
return z.union(schemas);
}
const firstSchema = schemas.at(0);
if (firstSchema) {
return firstSchema;
}
return hasDirectNonJsonEntry ? z.never() : null;
};
/** @deprecated No known consumers — will be removed in a future release. */
export const getIsEmptyResponseExpected = (routeConfig) => {
let isEmptyResponseExpected = true;
for (const code of SUCCESSFUL_HTTP_STATUS_CODES) {
const value = routeConfig.responsesByStatusCode[code];
if (value && value !== ContractNoBody && !isNoBodyResponse(value)) {
isEmptyResponseExpected = false;
break;
}
}
return isEmptyResponseExpected;
};
//# sourceMappingURL=defineApiContract.js.map