@zimic/http
Version:
Next-gen TypeScript-first HTTP utilities
1,085 lines (1,072 loc) • 61.7 kB
JavaScript
'use strict';
var filesystem = require('fs/promises');
var path = require('path');
var ts3 = require('typescript');
var color = require('picocolors');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var filesystem__default = /*#__PURE__*/_interopDefault(filesystem);
var path__default = /*#__PURE__*/_interopDefault(path);
var ts3__default = /*#__PURE__*/_interopDefault(ts3);
var color__default = /*#__PURE__*/_interopDefault(color);
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// ../zimic-utils/dist/chunk-2D3UJWOA.mjs
var __defProp2 = Object.defineProperty;
var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", { value, configurable: true }), "__name");
// ../zimic-utils/dist/chunk-WC2DBWWR.mjs
function isDefined(value) {
return value !== void 0 && value !== null;
}
__name(isDefined, "isDefined");
__name2(isDefined, "isDefined");
var isDefined_default = isDefined;
function isNeverType(type) {
return type.kind === ts3__default.default.SyntaxKind.NeverKeyword;
}
__name(isNeverType, "isNeverType");
function isUnknownType(type) {
return type.kind === ts3__default.default.SyntaxKind.UnknownKeyword;
}
__name(isUnknownType, "isUnknownType");
function isNullType(type) {
return type.kind === ts3__default.default.SyntaxKind.NullKeyword;
}
__name(isNullType, "isNullType");
function createBlobType() {
return ts3__default.default.factory.createTypeReferenceNode("Blob");
}
__name(createBlobType, "createBlobType");
function createNullType() {
return ts3__default.default.factory.createLiteralTypeNode(ts3__default.default.factory.createNull());
}
__name(createNullType, "createNullType");
function createImportSpecifier(importName) {
return ts3__default.default.factory.createImportSpecifier(false, void 0, ts3__default.default.factory.createIdentifier(importName));
}
__name(createImportSpecifier, "createImportSpecifier");
function createImportDeclaration(importSpecifiers, moduleName, options) {
return ts3__default.default.factory.createImportDeclaration(
void 0,
ts3__default.default.factory.createImportClause(
options.typeOnly ? ts3__default.default.SyntaxKind.TypeKeyword : void 0,
void 0,
ts3__default.default.factory.createNamedImports(importSpecifiers)
),
ts3__default.default.factory.createStringLiteral(moduleName)
);
}
__name(createImportDeclaration, "createImportDeclaration");
// src/types/schema.ts
var HTTP_METHODS = Object.freeze(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
// ../zimic-utils/dist/logging/Logger.mjs
var Logger = class _Logger {
static {
__name(this, "_Logger");
}
static {
__name2(this, "Logger");
}
prefix;
raw;
constructor(options = {}) {
const { prefix } = options;
this.prefix = prefix;
this.raw = prefix ? new _Logger({ ...options, prefix: void 0 }) : this;
}
logWithLevel(level, ...messages) {
if (this.prefix) {
console[level](this.prefix, ...messages);
} else {
console[level](...messages);
}
}
info(...messages) {
this.logWithLevel("log", ...messages);
}
warn(...messages) {
this.logWithLevel("warn", ...messages);
}
error(...messages) {
this.logWithLevel("error", ...messages);
}
table(headers, rows) {
const columnLengths = headers.map((header) => {
let maxValueLength = header.title.length;
for (const row of rows) {
const value = row[header.property];
if (value.length > maxValueLength) {
maxValueLength = value.length;
}
}
return maxValueLength;
});
const formattedRows = [];
const horizontalLine = columnLengths.map((length) => "\u2500".repeat(length));
formattedRows.push(horizontalLine, []);
for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
const header = headers[headerIndex];
const columnLength = columnLengths[headerIndex];
const value = header.title;
formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
}
formattedRows.push(horizontalLine);
for (const row of rows) {
formattedRows.push([]);
for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
const header = headers[headerIndex];
const columnLength = columnLengths[headerIndex];
const value = row[header.property];
formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
}
}
formattedRows.push(horizontalLine);
const formattedTable = formattedRows.map((row, index) => {
const isFirstLine = index === 0;
if (isFirstLine) {
return `\u250C\u2500${row.join("\u2500\u252C\u2500")}\u2500\u2510`;
}
const isLineAfterHeaders = index === 2;
if (isLineAfterHeaders) {
return `\u251C\u2500${row.join("\u2500\u253C\u2500")}\u2500\u2524`;
}
const isLastLine = index === formattedRows.length - 1;
if (isLastLine) {
return `\u2514\u2500${row.join("\u2500\u2534\u2500")}\u2500\u2518`;
}
return `\u2502 ${row.join(" \u2502 ")} \u2502`;
}).join("\n");
this.logWithLevel("log", formattedTable);
}
};
var Logger_default = Logger;
var logger = new Logger_default({
prefix: color__default.default.cyan("[@zimic/http]")
});
function createOperationsIdentifierText(serviceName) {
return `${serviceName}Operations`;
}
__name(createOperationsIdentifierText, "createOperationsIdentifierText");
function createOperationsIdentifier(serviceName) {
return ts3__default.default.factory.createIdentifier(createOperationsIdentifierText(serviceName));
}
__name(createOperationsIdentifier, "createOperationsIdentifier");
function isOperationsDeclaration(node) {
return node !== void 0 && ts3__default.default.isInterfaceDeclaration(node) && node.name.text === "operations";
}
__name(isOperationsDeclaration, "isOperationsDeclaration");
function isOperation(node) {
return ts3__default.default.isPropertySignature(node) && (ts3__default.default.isIdentifier(node.name) || ts3__default.default.isStringLiteral(node.name)) && node.type !== void 0 && ts3__default.default.isTypeLiteralNode(node.type);
}
__name(isOperation, "isOperation");
function normalizeOperation(operation, context) {
if (!isOperation(operation)) {
return void 0;
}
const newType = normalizeTypeLiteralMethodType(operation.type, context);
return ts3__default.default.factory.updatePropertySignature(
operation,
operation.modifiers,
operation.name,
operation.questionToken,
newType
);
}
__name(normalizeOperation, "normalizeOperation");
function normalizeOperations(operations, context) {
const newIdentifier = createOperationsIdentifier(context.serviceName);
const newMembers = operations.members.map((operation) => normalizeOperation(operation, context)).filter(isDefined_default);
return ts3__default.default.factory.updateInterfaceDeclaration(
operations,
operations.modifiers,
newIdentifier,
operations.typeParameters,
operations.heritageClauses,
newMembers
);
}
__name(normalizeOperations, "normalizeOperations");
function removeOperationIfUnreferenced(operation, context) {
if (!isOperation(operation)) {
return void 0;
}
const operationName = operation.name.text;
const isReferenced = context.referencedTypes.operations.has(operationName);
if (isReferenced) {
context.referencedTypes.operations.delete(operationName);
return operation;
}
return void 0;
}
__name(removeOperationIfUnreferenced, "removeOperationIfUnreferenced");
function removeUnreferencedOperations(operations, context) {
const newMembers = operations.members.map((operation) => removeOperationIfUnreferenced(operation, context)).filter(isDefined_default);
context.referencedTypes.operations.clear();
if (newMembers.length === 0) {
return void 0;
}
return ts3__default.default.factory.updateInterfaceDeclaration(
operations,
operations.modifiers,
operations.name,
operations.typeParameters,
operations.heritageClauses,
newMembers
);
}
__name(removeUnreferencedOperations, "removeUnreferencedOperations");
// src/typegen/openapi/transform/methods.ts
function isMethod(node) {
return ts3__default.default.isPropertySignature(node) && ts3__default.default.isIdentifier(node.name) && node.type !== void 0 && (ts3__default.default.isTypeLiteralNode(node.type) || ts3__default.default.isIndexedAccessTypeNode(node.type));
}
__name(isMethod, "isMethod");
function isMethodMember(node) {
return ts3__default.default.isPropertySignature(node) && ts3__default.default.isIdentifier(node.name) && node.type !== void 0 && (ts3__default.default.isTypeLiteralNode(node.type) || ts3__default.default.isIndexedAccessTypeNode(node.type) || isNeverType(node.type));
}
__name(isMethodMember, "isMethodMember");
function isRequestMember(node) {
return ts3__default.default.isPropertySignature(node) && ts3__default.default.isIdentifier(node.name) && node.type !== void 0 && !isNeverType(node.type);
}
__name(isRequestMember, "isRequestMember");
function isRequestHeaders(node) {
return isRequestMember(node) && node.name.text === "headers" && ts3__default.default.isTypeLiteralNode(node.type);
}
__name(isRequestHeaders, "isRequestHeaders");
function isNormalizedRequestHeaders(node) {
return isRequestMember(node) && node.name.text === "headers" && ts3__default.default.isTypeLiteralNode(node.type);
}
__name(isNormalizedRequestHeaders, "isNormalizedRequestHeaders");
function isRequestParameters(node) {
return isRequestMember(node) && node.name.text === "parameters" && ts3__default.default.isTypeLiteralNode(node.type);
}
__name(isRequestParameters, "isRequestParameters");
function isContentPropertySignature(node) {
return isRequestMember(node) && node.name.text === "content" && ts3__default.default.isTypeLiteralNode(node.type);
}
__name(isContentPropertySignature, "isContentPropertySignature");
function isContentMember(node) {
return ts3__default.default.isPropertySignature(node) && (ts3__default.default.isIdentifier(node.name) || ts3__default.default.isStringLiteral(node.name)) && node.type !== void 0 && !isNeverType(node.type);
}
__name(isContentMember, "isContentMember");
function isResponse(node) {
return ts3__default.default.isPropertySignature(node) && (ts3__default.default.isIdentifier(node.name) || ts3__default.default.isStringLiteral(node.name) || ts3__default.default.isNumericLiteral(node.name)) && node.type !== void 0;
}
__name(isResponse, "isResponse");
function removeRedundantNullUnionIfNecessary(type) {
const containsRedundantNullUnion = ts3__default.default.isUnionTypeNode(type) && type.types.some((type2) => {
const isNull = ts3__default.default.isLiteralTypeNode(type2) && isNullType(type2.literal);
return isNull;
}) && type.types.some((type2) => {
return ts3__default.default.isParenthesizedTypeNode(type2) && ts3__default.default.isUnionTypeNode(type2.type) && type2.type.types.some((subType) => {
const isNull = ts3__default.default.isLiteralTypeNode(subType) && isNullType(subType.literal);
return isNull;
});
});
if (!containsRedundantNullUnion) {
return type;
}
const typesWithoutRedundantNullUnion = type.types.filter((type2) => {
const isNull = ts3__default.default.isLiteralTypeNode(type2) && isNullType(type2.literal);
return !isNull;
}).flatMap((type2) => {
if (ts3__default.default.isParenthesizedTypeNode(type2) && ts3__default.default.isUnionTypeNode(type2.type)) {
return type2.type.types;
}
return [type2];
});
return ts3__default.default.factory.createUnionTypeNode(typesWithoutRedundantNullUnion);
}
__name(removeRedundantNullUnionIfNecessary, "removeRedundantNullUnionIfNecessary");
function wrapFormDataContentType(type, context) {
context.typeImports.http.add("HttpFormData");
return ts3__default.default.factory.createTypeReferenceNode(ts3__default.default.factory.createIdentifier("HttpFormData"), [
renameComponentReferences(type, context)
]);
}
__name(wrapFormDataContentType, "wrapFormDataContentType");
function wrapURLEncodedContentType(type, context) {
context.typeImports.http.add("HttpSearchParams");
return ts3__default.default.factory.createTypeReferenceNode(ts3__default.default.factory.createIdentifier("HttpSearchParams"), [
renameComponentReferences(type, context)
]);
}
__name(wrapURLEncodedContentType, "wrapURLEncodedContentType");
function normalizeRequestBodyMember(requestBodyMember, context, options) {
if (!isContentMember(requestBodyMember)) {
return void 0;
}
const newIdentifier = ts3__default.default.factory.createIdentifier("body");
const contentType = requestBodyMember.name.text;
let newType = removeRedundantNullUnionIfNecessary(renameComponentReferences(requestBodyMember.type, context));
if (contentType === "multipart/form-data") {
newType = wrapFormDataContentType(newType, context);
} else if (contentType === "x-www-form-urlencoded") {
newType = wrapURLEncodedContentType(newType, context);
}
return {
contentTypeName: contentType,
propertySignature: ts3__default.default.factory.updatePropertySignature(
requestBodyMember,
requestBodyMember.modifiers,
newIdentifier,
options.questionToken,
newType
)
};
}
__name(normalizeRequestBodyMember, "normalizeRequestBodyMember");
function normalizeHeaders(headers) {
const newHeaderMembers = headers.members.filter((header) => {
if (ts3__default.default.isIndexSignatureDeclaration(header)) {
return false;
}
if (ts3__default.default.isPropertySignature(header)) {
return header.type !== void 0 && !isUnknownType(header.type);
}
return true;
});
if (newHeaderMembers.length === 0) {
return void 0;
}
return ts3__default.default.factory.updateTypeLiteralNode(headers, ts3__default.default.factory.createNodeArray(newHeaderMembers));
}
__name(normalizeHeaders, "normalizeHeaders");
function normalizeRequestHeaders(requestHeader) {
if (!isRequestHeaders(requestHeader)) {
return void 0;
}
const newType = normalizeHeaders(requestHeader.type);
if (!newType) {
return void 0;
}
return ts3__default.default.factory.updatePropertySignature(
requestHeader,
requestHeader.modifiers,
requestHeader.name,
requestHeader.questionToken,
newType
);
}
__name(normalizeRequestHeaders, "normalizeRequestHeaders");
function createHeaderForUnionByContentType(existingHeader, contentTypeName) {
const existingHeaderMembers = existingHeader?.type.members ?? [];
const contentTypeIdentifier = ts3__default.default.factory.createIdentifier('"content-type"');
const contentTypeValue = ts3__default.default.factory.createLiteralTypeNode(ts3__default.default.factory.createStringLiteral(contentTypeName));
const newHeaderType = ts3__default.default.factory.createTypeLiteralNode([
ts3__default.default.factory.createPropertySignature(void 0, contentTypeIdentifier, void 0, contentTypeValue),
...existingHeaderMembers
]);
return ts3__default.default.factory.createPropertySignature(
existingHeader?.modifiers,
ts3__default.default.factory.createIdentifier("headers"),
void 0,
newHeaderType
);
}
__name(createHeaderForUnionByContentType, "createHeaderForUnionByContentType");
function normalizeContentType(contentType, context, options) {
const { bodyQuestionToken } = options;
if (ts3__default.default.isIndexedAccessTypeNode(contentType)) {
return renameComponentReferences(contentType, context);
}
if (!ts3__default.default.isTypeLiteralNode(contentType)) {
return contentType;
}
const newHeader = contentType.members.map(normalizeRequestHeaders).find(isDefined_default);
const newBodyMembers = contentType.members.flatMap((body) => {
if (isContentPropertySignature(body)) {
return body.type.members.map((member) => normalizeRequestBodyMember(member, context, { questionToken: bodyQuestionToken })).filter(isDefined_default);
}
return [];
});
if (newBodyMembers.length === 0) {
const newMembers = [newHeader].filter(isDefined_default);
return ts3__default.default.factory.updateTypeLiteralNode(contentType, ts3__default.default.factory.createNodeArray(newMembers));
} else {
const bodyMemberUnionTypes = newBodyMembers.map((bodyMember) => {
const headerMember = createHeaderForUnionByContentType(newHeader, bodyMember.contentTypeName);
return ts3__default.default.factory.createTypeLiteralNode([headerMember, bodyMember.propertySignature]);
});
return ts3__default.default.factory.createUnionTypeNode(bodyMemberUnionTypes);
}
}
__name(normalizeContentType, "normalizeContentType");
function normalizeRequest(request, context) {
const newIdentifier = ts3__default.default.factory.createIdentifier("request");
const newType = normalizeContentType(request.type, context, {
bodyQuestionToken: request.questionToken
});
if (request.questionToken && ts3__default.default.isIndexedAccessTypeNode(request.type) && ts3__default.default.isLiteralTypeNode(request.type.indexType) && (ts3__default.default.isIdentifier(request.type.indexType.literal) || ts3__default.default.isStringLiteral(request.type.indexType.literal))) {
const referencedComponentName = request.type.indexType.literal.text;
context.pendingActions.components.requests.toMarkBodyAsOptional.add(referencedComponentName);
}
return ts3__default.default.factory.updatePropertySignature(request, request.modifiers, newIdentifier, void 0, newType);
}
__name(normalizeRequest, "normalizeRequest");
function normalizeResponseType(responseType, context, options) {
const { questionToken } = options;
if (!ts3__default.default.isTypeLiteralNode(responseType)) {
return responseType;
}
return normalizeContentType(responseType, context, { bodyQuestionToken: questionToken });
}
__name(normalizeResponseType, "normalizeResponseType");
var NON_NUMERIC_RESPONSE_STATUS_TO_MAPPED_TYPE = {
default: "HttpStatusCode",
"1xx": "HttpStatusCode.Information",
"2xx": "HttpStatusCode.Success",
"3xx": "HttpStatusCode.Redirection",
"4xx": "HttpStatusCode.ClientError",
"5xx": "HttpStatusCode.ServerError"
};
function normalizeResponse(response, context, options = {}) {
const { isComponent: isComponent2 = false } = options;
if (!isResponse(response)) {
return void 0;
}
const newType = normalizeResponseType(response.type, context, {
questionToken: response.questionToken
});
const statusCodeOrComponentName = response.name.text;
const isNumericStatusCode = /^\d+$/.test(statusCodeOrComponentName);
const shouldReuseIdentifier = isComponent2 || isNumericStatusCode;
let newSignature;
if (shouldReuseIdentifier) {
newSignature = ts3__default.default.factory.updatePropertySignature(
response,
response.modifiers,
response.name,
response.questionToken,
newType
);
} else {
const statusCode = statusCodeOrComponentName.toLowerCase();
const mappedType = NON_NUMERIC_RESPONSE_STATUS_TO_MAPPED_TYPE[statusCode];
if (!mappedType) {
logger.warn(
`Warning: Response has a non-standard status code: ${color__default.default.yellow(response.name.text)}. Consider replacing it with a number (e.g. '200'), a pattern ('1xx', '2xx', '3xx', '4xx', or '5xx'), or 'default'.`
);
return void 0;
}
context.typeImports.http.add("HttpStatusCode");
const newIdentifier = ts3__default.default.factory.createIdentifier(`[StatusCode in ${mappedType}]`);
newSignature = ts3__default.default.factory.updatePropertySignature(
response,
response.modifiers,
newIdentifier,
response.questionToken,
newType
);
}
return {
newSignature,
statusCode: {
value: statusCodeOrComponentName,
isNumeric: isNumericStatusCode
}
};
}
__name(normalizeResponse, "normalizeResponse");
function normalizeResponses(responses, context) {
if (isNeverType(responses.type) || !ts3__default.default.isTypeLiteralNode(responses.type)) {
return void 0;
}
const newIdentifier = ts3__default.default.factory.createIdentifier("response");
const newQuestionToken = void 0;
const newMembers = responses.type.members.map((response) => normalizeResponse(response, context), context).filter(isDefined_default);
const sortedNewMembers = Array.from(newMembers).sort((response, otherResponse) => {
return response.statusCode.value.localeCompare(otherResponse.statusCode.value);
});
const isEveryStatusCodeNumeric = sortedNewMembers.every((response) => response.statusCode.isNumeric);
let newType;
if (isEveryStatusCodeNumeric) {
newType = ts3__default.default.factory.updateTypeLiteralNode(
responses.type,
ts3__default.default.factory.createNodeArray(sortedNewMembers.map((response) => response.newSignature))
);
} else {
context.typeImports.http.add("MergeHttpResponsesByStatusCode");
const typeMembersToMerge = sortedNewMembers.reduce(
(members, response) => {
if (response.statusCode.isNumeric) {
members.numeric.push(response.newSignature);
} else {
members.nonNumeric.push(response.newSignature);
}
return members;
},
{ numeric: [], nonNumeric: [] }
);
const numericTypeLiteral = ts3__default.default.factory.createTypeLiteralNode(typeMembersToMerge.numeric);
const nonNumericTypeLiterals = typeMembersToMerge.nonNumeric.map(
(response) => ts3__default.default.factory.createTypeLiteralNode([response])
);
const mergeWrapper = ts3__default.default.factory.createIdentifier("MergeHttpResponsesByStatusCode");
newType = ts3__default.default.factory.createTypeReferenceNode(mergeWrapper, [
ts3__default.default.factory.createTupleTypeNode([numericTypeLiteral, ...nonNumericTypeLiterals])
]);
}
return ts3__default.default.factory.updatePropertySignature(
responses,
responses.modifiers,
newIdentifier,
newQuestionToken,
renameComponentReferences(newType, context)
);
}
__name(normalizeResponses, "normalizeResponses");
function normalizeMethodMember(methodMember, context) {
if (isMethodMember(methodMember)) {
if (methodMember.name.text === "requestBody") {
return normalizeRequest(methodMember, context);
}
if (methodMember.name.text === "responses") {
return normalizeResponses(methodMember, context);
}
return methodMember;
}
return void 0;
}
__name(normalizeMethodMember, "normalizeMethodMember");
function normalizeRequestQueryWithParameters(requestMember, context) {
const newIdentifier = ts3__default.default.factory.createIdentifier("searchParams");
const newQuestionToken = void 0;
const newType = renameComponentReferences(requestMember.type, context);
return ts3__default.default.factory.updatePropertySignature(
requestMember,
requestMember.modifiers,
newIdentifier,
newQuestionToken,
newType
);
}
__name(normalizeRequestQueryWithParameters, "normalizeRequestQueryWithParameters");
function normalizeRequestHeadersWithParameters(requestMember, context) {
const newIdentifier = ts3__default.default.factory.createIdentifier("headers");
const newQuestionToken = void 0;
const newType = renameComponentReferences(requestMember.type, context);
return ts3__default.default.factory.updatePropertySignature(
requestMember,
requestMember.modifiers,
newIdentifier,
newQuestionToken,
newType
);
}
__name(normalizeRequestHeadersWithParameters, "normalizeRequestHeadersWithParameters");
function normalizeRequestMemberWithParameters(requestMember, context) {
if (!isRequestMember(requestMember) || requestMember.name.text === "path") {
return void 0;
}
if (requestMember.name.text === "query") {
return normalizeRequestQueryWithParameters(requestMember, context);
}
if (requestMember.name.text === "header") {
return normalizeRequestHeadersWithParameters(requestMember, context);
}
return requestMember;
}
__name(normalizeRequestMemberWithParameters, "normalizeRequestMemberWithParameters");
function mergeRequestHeadersMember(headers, otherHeaders) {
const newType = ts3__default.default.factory.updateTypeLiteralNode(
headers.type,
ts3__default.default.factory.createNodeArray([...otherHeaders.type.members, ...headers.type.members])
);
return ts3__default.default.factory.updatePropertySignature(
headers,
headers.modifiers,
headers.name,
headers.questionToken,
newType
);
}
__name(mergeRequestHeadersMember, "mergeRequestHeadersMember");
function mergeRequestHeadersMembers(members) {
let mergedHeaders;
let firstHeadersIndex;
const mergedHeadersMembers = members.map((member, index) => {
if (!member || !isNormalizedRequestHeaders(member)) {
return member;
}
if (firstHeadersIndex === void 0 || !mergedHeaders) {
firstHeadersIndex = index;
mergedHeaders = member;
return member;
}
mergedHeaders = mergeRequestHeadersMember(mergedHeaders, member);
return void 0;
});
if (firstHeadersIndex !== void 0) {
mergedHeadersMembers[firstHeadersIndex] = mergedHeaders;
}
return mergedHeadersMembers.filter(isDefined_default);
}
__name(mergeRequestHeadersMembers, "mergeRequestHeadersMembers");
function mergeRequestAndParameterTypes(requestType, methodMembers, context) {
const parameters = methodMembers.find(isRequestParameters);
const parametersMembers = parameters ? parameters.type.members : [];
const requestMembers = ts3__default.default.isTypeLiteralNode(requestType) ? requestType.members : [];
const newMembers = mergeRequestHeadersMembers(
[...parametersMembers, ...requestMembers].map((member) => {
return normalizeRequestMemberWithParameters(member, context);
})
);
if (newMembers.length === 0) {
return void 0;
}
return ts3__default.default.factory.createTypeLiteralNode(newMembers);
}
__name(mergeRequestAndParameterTypes, "mergeRequestAndParameterTypes");
function normalizeRequestTypeWithParameters(requestType, methodMembers, context) {
if (ts3__default.default.isUnionTypeNode(requestType)) {
const newTypes = requestType.types.map((type) => normalizeRequestTypeWithParameters(type, methodMembers, context)).filter(isDefined_default);
return ts3__default.default.factory.updateUnionTypeNode(requestType, ts3__default.default.factory.createNodeArray(newTypes));
}
if (ts3__default.default.isIndexedAccessTypeNode(requestType)) {
const newType = normalizeRequestTypeWithParameters(ts3__default.default.factory.createTypeLiteralNode([]), methodMembers, context);
return ts3__default.default.factory.createIntersectionTypeNode([requestType, newType].filter(isDefined_default));
}
return mergeRequestAndParameterTypes(requestType, methodMembers, context);
}
__name(normalizeRequestTypeWithParameters, "normalizeRequestTypeWithParameters");
function normalizeMethodMemberWithParameters(methodMember, methodMembers, context) {
if (!ts3__default.default.isIdentifier(methodMember.name) || !methodMember.type) {
return void 0;
}
if (methodMember.name.text === "request") {
const newType = normalizeRequestTypeWithParameters(methodMember.type, methodMembers, context);
if (!newType) {
return void 0;
}
return ts3__default.default.factory.updatePropertySignature(
methodMember,
methodMember.modifiers,
methodMember.name,
void 0,
newType
);
}
if (methodMember.name.text === "response") {
return methodMember;
}
return void 0;
}
__name(normalizeMethodMemberWithParameters, "normalizeMethodMemberWithParameters");
function normalizeTypeLiteralMethodType(methodType, context) {
const newMembers = methodType.members.map((member) => normalizeMethodMember(member, context)).filter(isDefined_default).map((member, _index, partialMembers) => normalizeMethodMemberWithParameters(member, partialMembers, context)).filter(isDefined_default);
return ts3__default.default.factory.updateTypeLiteralNode(methodType, ts3__default.default.factory.createNodeArray(newMembers));
}
__name(normalizeTypeLiteralMethodType, "normalizeTypeLiteralMethodType");
function normalizeIndexedAccessMethodType(methodType, context) {
const isOperationsReference = ts3__default.default.isTypeReferenceNode(methodType.objectType) && ts3__default.default.isIdentifier(methodType.objectType.typeName) && methodType.objectType.typeName.text === "operations";
if (!isOperationsReference) {
return methodType;
}
const newIdentifier = createOperationsIdentifier(context.serviceName);
const newObjectType = ts3__default.default.factory.createTypeReferenceNode(newIdentifier, methodType.objectType.typeArguments);
const hasIndexTypeName = ts3__default.default.isLiteralTypeNode(methodType.indexType) && (ts3__default.default.isIdentifier(methodType.indexType.literal) || ts3__default.default.isStringLiteral(methodType.indexType.literal));
if (hasIndexTypeName) {
const operationName = methodType.indexType.literal.text;
context.referencedTypes.operations.add(operationName);
}
return ts3__default.default.factory.updateIndexedAccessTypeNode(methodType, newObjectType, methodType.indexType);
}
__name(normalizeIndexedAccessMethodType, "normalizeIndexedAccessMethodType");
function normalizeMethod(method, context, options) {
if (!isMethod(method)) {
return void 0;
}
const methodName = method.name.text.toUpperCase();
if (!HTTP_METHODS.includes(methodName)) {
return void 0;
}
const pathMethodCompareString = `${methodName} ${options.pathName}`;
const matchesPositiveFilters = context.filters.paths.positive.length === 0 || context.filters.paths.positive.some((filter) => filter.test(pathMethodCompareString));
const matchesNegativeFilters = context.filters.paths.negative.length > 0 && context.filters.paths.negative.some((filter) => filter.test(pathMethodCompareString));
if (!matchesPositiveFilters || matchesNegativeFilters) {
return void 0;
}
const newIdentifier = ts3__default.default.factory.createIdentifier(methodName);
const newType = ts3__default.default.isTypeLiteralNode(method.type) ? normalizeTypeLiteralMethodType(method.type, context) : normalizeIndexedAccessMethodType(method.type, context);
return ts3__default.default.factory.updatePropertySignature(method, method.modifiers, newIdentifier, method.questionToken, newType);
}
__name(normalizeMethod, "normalizeMethod");
function createPathsIdentifier(serviceName) {
return ts3__default.default.factory.createIdentifier(`${serviceName}Schema`);
}
__name(createPathsIdentifier, "createPathsIdentifier");
function isPathsDeclaration(node) {
return node !== void 0 && (ts3__default.default.isInterfaceDeclaration(node) || ts3__default.default.isTypeAliasDeclaration(node)) && node.name.text === "paths";
}
__name(isPathsDeclaration, "isPathsDeclaration");
function isPath(node) {
return ts3__default.default.isPropertySignature(node) && (ts3__default.default.isIdentifier(node.name) || ts3__default.default.isStringLiteral(node.name)) && node.type !== void 0 && (ts3__default.default.isTypeLiteralNode(node.type) || ts3__default.default.isIndexedAccessTypeNode(node.type));
}
__name(isPath, "isPath");
function normalizePathNameWithParameters(pathName) {
return pathName.replace(/{([^}]+)}/g, ":$1");
}
__name(normalizePathNameWithParameters, "normalizePathNameWithParameters");
function normalizePath(path4, context, options = {}) {
const { isComponent: isComponent2 = false } = options;
if (!isPath(path4)) {
return void 0;
}
const newPathName = isComponent2 ? path4.name.text : normalizePathNameWithParameters(path4.name.text);
const newIdentifier = isComponent2 ? path4.name : ts3__default.default.factory.createStringLiteral(newPathName);
let newType;
if (ts3__default.default.isTypeLiteralNode(path4.type)) {
const newMethods = path4.type.members.map((method) => normalizeMethod(method, context, { pathName: newPathName })).filter(isDefined_default);
if (newMethods.length === 0) {
return void 0;
}
newType = ts3__default.default.factory.updateTypeLiteralNode(path4.type, ts3__default.default.factory.createNodeArray(newMethods));
} else {
newType = renameComponentReferences(path4.type, context);
}
return ts3__default.default.factory.updatePropertySignature(path4, path4.modifiers, newIdentifier, path4.questionToken, newType);
}
__name(normalizePath, "normalizePath");
function wrapPathsType(type, context) {
context.typeImports.http.add("HttpSchema");
const httpSchemaPathsWrapper = ts3__default.default.factory.createIdentifier("HttpSchema");
return ts3__default.default.factory.createTypeReferenceNode(httpSchemaPathsWrapper, [type]);
}
__name(wrapPathsType, "wrapPathsType");
function normalizePaths(pathsOrTypeAlias, context) {
const newIdentifier = createPathsIdentifier(context.serviceName);
const paths = ts3__default.default.isTypeAliasDeclaration(pathsOrTypeAlias) ? ts3__default.default.factory.createInterfaceDeclaration(pathsOrTypeAlias.modifiers, pathsOrTypeAlias.name, void 0, void 0, []) : pathsOrTypeAlias;
const newMembers = paths.members.map((path4) => normalizePath(path4, context)).filter(isDefined_default);
const newType = ts3__default.default.factory.createTypeLiteralNode(newMembers);
return ts3__default.default.factory.createTypeAliasDeclaration(
paths.modifiers,
newIdentifier,
paths.typeParameters,
wrapPathsType(newType, context)
);
}
__name(normalizePaths, "normalizePaths");
// src/typegen/openapi/transform/components.ts
function createComponentsIdentifierText(serviceName) {
return `${serviceName}Components`;
}
__name(createComponentsIdentifierText, "createComponentsIdentifierText");
function createComponentsIdentifier(serviceName) {
return ts3__default.default.factory.createIdentifier(createComponentsIdentifierText(serviceName));
}
__name(createComponentsIdentifier, "createComponentsIdentifier");
function isComponentsDeclaration(node, context) {
const componentIdentifiers = ["components", createComponentsIdentifierText(context.serviceName)];
return node !== void 0 && ts3__default.default.isInterfaceDeclaration(node) && componentIdentifiers.includes(node.name.text);
}
__name(isComponentsDeclaration, "isComponentsDeclaration");
function isComponentGroup(node) {
return ts3__default.default.isPropertySignature(node) && node.type !== void 0 && ts3__default.default.isTypeLiteralNode(node.type) && ts3__default.default.isIdentifier(node.name);
}
__name(isComponentGroup, "isComponentGroup");
function isComponent(node) {
return ts3__default.default.isPropertySignature(node) && node.type !== void 0 && !isNeverType(node.type) && (ts3__default.default.isIdentifier(node.name) || ts3__default.default.isStringLiteral(node.name));
}
__name(isComponent, "isComponent");
function isRequestComponent(node) {
return ts3__default.default.isTypeLiteralNode(node.type);
}
__name(isRequestComponent, "isRequestComponent");
function unchangedIndexedAccessTypeNode(node) {
return node;
}
__name(unchangedIndexedAccessTypeNode, "unchangedIndexedAccessTypeNode");
function visitComponentReferences(node, context, options) {
const { onComponentReference, renameComponentReference = unchangedIndexedAccessTypeNode } = options;
if (isUnknownType(node)) {
return ts3__default.default.factory.createKeywordTypeNode(ts3__default.default.SyntaxKind.AnyKeyword);
}
if (ts3__default.default.isTypeReferenceNode(node)) {
const newTypeArguments = node.typeArguments?.map((type) => visitComponentReferences(type, context, options));
return ts3__default.default.factory.updateTypeReferenceNode(node, node.typeName, ts3__default.default.factory.createNodeArray(newTypeArguments));
}
if (ts3__default.default.isArrayTypeNode(node)) {
const newElementType = visitComponentReferences(node.elementType, context, options);
return ts3__default.default.factory.updateArrayTypeNode(node, newElementType);
}
if (ts3__default.default.isTupleTypeNode(node)) {
const newElements = node.elements.map((element) => visitComponentReferences(element, context, options));
return ts3__default.default.factory.updateTupleTypeNode(node, ts3__default.default.factory.createNodeArray(newElements));
}
if (ts3__default.default.isUnionTypeNode(node)) {
const newTypes = node.types.map((type) => visitComponentReferences(type, context, options));
return ts3__default.default.factory.updateUnionTypeNode(node, ts3__default.default.factory.createNodeArray(newTypes));
}
if (ts3__default.default.isIntersectionTypeNode(node)) {
const newTypes = node.types.map((type) => visitComponentReferences(type, context, options));
return ts3__default.default.factory.updateIntersectionTypeNode(node, ts3__default.default.factory.createNodeArray(newTypes));
}
if (ts3__default.default.isParenthesizedTypeNode(node)) {
const newType = visitComponentReferences(node.type, context, options);
return ts3__default.default.factory.updateParenthesizedType(node, newType);
}
if (ts3__default.default.isTypeLiteralNode(node)) {
const newMembers = node.members.map((member) => {
if (ts3__default.default.isPropertySignature(member) && member.type) {
const newType = visitComponentReferences(member.type, context, options);
return ts3__default.default.factory.updatePropertySignature(member, member.modifiers, member.name, member.questionToken, newType);
}
if (ts3__default.default.isIndexSignatureDeclaration(member)) {
const newType = visitComponentReferences(member.type, context, options);
return ts3__default.default.factory.updateIndexSignature(member, member.modifiers, member.parameters, newType);
}
return member;
});
return ts3__default.default.factory.updateTypeLiteralNode(node, ts3__default.default.factory.createNodeArray(newMembers));
}
if (ts3__default.default.isIndexedAccessTypeNode(node)) {
const isRootIndexedAccess = context.isComponentIndexedAccess ?? true;
if (ts3__default.default.isIndexedAccessTypeNode(node.objectType)) {
const childContext = { ...context, isComponentIndexedAccess: false };
const newObjectType = visitComponentReferences(node.objectType, childContext, options);
const newNode = ts3__default.default.factory.updateIndexedAccessTypeNode(node, newObjectType, node.indexType);
if (childContext.partialComponentPath && childContext.partialComponentPath.length > 0) {
const hasIndexTypeName = ts3__default.default.isLiteralTypeNode(node.indexType) && (ts3__default.default.isIdentifier(node.indexType.literal) || ts3__default.default.isStringLiteral(node.indexType.literal));
if (hasIndexTypeName) {
const componentName = node.indexType.literal.text;
childContext.partialComponentPath.push(componentName);
}
if (isRootIndexedAccess) {
const componentGroupName = childContext.partialComponentPath[0];
const componentName = childContext.partialComponentPath.slice(1).join(".");
const componentPath = `${componentGroupName}.${componentName}`;
onComponentReference(newNode, componentPath);
}
}
return newNode;
}
const componentIdentifiers = ["components", createComponentsIdentifierText(context.serviceName)];
const isComponentIndexedAccess = ts3__default.default.isTypeReferenceNode(node.objectType) && ts3__default.default.isIdentifier(node.objectType.typeName) && componentIdentifiers.includes(node.objectType.typeName.text) && ts3__default.default.isLiteralTypeNode(node.indexType) && (ts3__default.default.isIdentifier(node.indexType.literal) || ts3__default.default.isStringLiteral(node.indexType.literal));
if (isComponentIndexedAccess) {
const isRawComponent = node.objectType.typeName.text === "components";
const componentGroupName = node.indexType.literal.text;
const newNode = isRawComponent ? renameComponentReference(node, {
objectType: node.objectType,
indexType: node.indexType,
componentGroupName
}) : node;
const newNodeHasComponentGroupName = ts3__default.default.isLiteralTypeNode(newNode.indexType) && (ts3__default.default.isIdentifier(newNode.indexType.literal) || ts3__default.default.isStringLiteral(newNode.indexType.literal));
if (newNodeHasComponentGroupName) {
const newComponentGroupName = newNode.indexType.literal.text;
context.partialComponentPath = [newComponentGroupName];
}
return newNode;
}
}
return node;
}
__name(visitComponentReferences, "visitComponentReferences");
function normalizeComponentGroupName(rawComponentGroupName) {
if (rawComponentGroupName === "requestBodies") {
return "requests";
}
return rawComponentGroupName;
}
__name(normalizeComponentGroupName, "normalizeComponentGroupName");
function renameComponentReferences(node, context) {
return visitComponentReferences(node, context, {
onComponentReference(_node, componentPath) {
context.referencedTypes.components.add(componentPath);
},
renameComponentReference(node2, { indexType, objectType, componentGroupName }) {
const newIdentifier = createComponentsIdentifier(context.serviceName);
const newObjectType = ts3__default.default.factory.updateTypeReferenceNode(objectType, newIdentifier, objectType.typeArguments);
const newComponentGroupName = normalizeComponentGroupName(componentGroupName);
const newIndexType = ts3__default.default.factory.updateLiteralTypeNode(
indexType,
ts3__default.default.factory.createStringLiteral(newComponentGroupName)
);
return ts3__default.default.factory.updateIndexedAccessTypeNode(node2, newObjectType, newIndexType);
}
});
}
__name(renameComponentReferences, "renameComponentReferences");
function processPendingRequestComponentActions(component, context) {
const pendingRequestActions = context.pendingActions.components.requests;
const componentName = component.name.text;
const shouldBeMarkedAsOptional = pendingRequestActions.toMarkBodyAsOptional.has(componentName);
const bodyQuestionToken = shouldBeMarkedAsOptional ? ts3__default.default.factory.createToken(ts3__default.default.SyntaxKind.QuestionToken) : component.questionToken;
pendingRequestActions.toMarkBodyAsOptional.delete(componentName);
return { bodyQuestionToken };
}
__name(processPendingRequestComponentActions, "processPendingRequestComponentActions");
function normalizeRequestComponent(component, context) {
if (!isRequestComponent(component)) {
return void 0;
}
const { bodyQuestionToken } = processPendingRequestComponentActions(component, context);
const newType = normalizeContentType(component.type, context, { bodyQuestionToken });
return ts3__default.default.factory.updatePropertySignature(
component,
component.modifiers,
component.name,
component.questionToken,
newType
);
}
__name(normalizeRequestComponent, "normalizeRequestComponent");
function normalizeComponent(component, componentGroupName, context) {
if (!isComponent(component)) {
return void 0;
}
if (componentGroupName === "requests") {
return normalizeRequestComponent(component, context);
}
if (componentGroupName === "responses") {
const responseComponent = normalizeResponse(component, context, { isComponent: true });
return responseComponent?.newSignature;
}
if (componentGroupName === "pathItems") {
return normalizePath(component, context, { isComponent: true });
}
return ts3__default.default.factory.updatePropertySignature(
component,
component.modifiers,
component.name,
component.questionToken,
renameComponentReferences(component.type, context)
);
}
__name(normalizeComponent, "normalizeComponent");
function normalizeComponentGroup(componentGroup, context) {
if (!isComponentGroup(componentGroup)) {
return void 0;
}
const componentGroupName = normalizeComponentGroupName(componentGroup.name.text);
const newIdentifier = ts3__default.default.factory.createIdentifier(componentGroupName);
const newComponents = componentGroup.type.members.map((component) => normalizeComponent(component, componentGroupName, context)).filter(isDefined_default);
const newType = ts3__default.default.factory.updateTypeLiteralNode(componentGroup.type, ts3__default.default.factory.createNodeArray(newComponents));
return ts3__default.default.factory.updatePropertySignature(
componentGroup,
componentGroup.modifiers,
newIdentifier,
componentGroup.questionToken,
newType
);
}
__name(normalizeComponentGroup, "normalizeComponentGroup");
function normalizeComponents(components, context) {
const newIdentifier = createComponentsIdentifier(context.serviceName);
const newMembers = components.members.map((componentGroup) => normalizeComponentGroup(componentGroup, context)).filter(isDefined_default);
return ts3__default.default.factory.updateInterfaceDeclaration(
components,
components.modifiers,
newIdentifier,
components.typeParameters,
components.heritageClauses,
newMembers
);
}
__name(normalizeComponents, "normalizeComponents");
function populateReferencedComponents(components, context) {
const pathsToVisit = new Set(context.referencedTypes.components);
while (pathsToVisit.size > 0) {
const previousPathsToVisit = new Set(pathsToVisit);
pathsToVisit.clear();
for (const componentGroup of components.members) {
if (!isComponentGroup(componentGroup)) {
continue;
}
const componentGroupName = normalizeComponentGroupName(componentGroup.name.text);
for (const component of componentGroup.type.members) {
if (!isComponent(component)) {
continue;
}
const componentName = component.name.text;
const componentPath = `${componentGroupName}.${componentName}`;
const isComponentToVisit = previousPathsToVisit.has(componentPath);
if (!isComponentToVisit) {
continue;
}
context.referencedTypes.components.add(componentPath);
visitComponentReferences(component.type, context, {
onComponentReference(_node, componentPath2) {
const isKnownReferencedComponent = context.referencedTypes.components.has(componentPath2);
if (!isKnownReferencedComponent) {
pathsToVisit.add(componentPath2);
}
}
});
}
}
}
}
__name(populateReferencedComponents, "populateReferencedComponents");
function removeComponentIfUnreferenced(component, componentGroupName, context) {
if (!isComponent(component)) {
return void 0;
}
const componentName = component.name.text;
const componentPath = `${componentGroupName}.${componentName}`;
if (context.referencedTypes.components.has(componentPath)) {
context.referencedTypes.components.delete(componentPath);
return component;
}
return void 0;
}
__name(removeComponentIfUnreferenced, "removeComponentIfUnreferenced");
function removeUnreferencedComponentsInGroup(componentGroup, context) {
if (!isComponentGroup(componentGroup)) {
return void 0;
}
const componentGroupName = normalizeComponentGroupName(componentGroup.name.text);
const newComponents = componentGroup.type.members.map((component) => removeComponentIfUnreferenced(component, componentGroupName, context)).filter(isDefined_default);
if (newComponents.length === 0) {
return void 0;
}
return ts3__default.default.factory.updatePropertySignature(
componentGroup,
componentGroup.modifiers,
componentGroup.name,
componentGroup.questionToken,
ts3__default.default.factory.updateTypeLiteralNode(componentGroup.type, ts3__default.default.factory.createNodeArray(newComponents))
);
}
__name(removeUnreferencedComponentsInGroup, "removeUnreferencedComponentsInGroup");
function removeUnreferencedComponents(components, context) {
const newComponentGroups = components.members.map((componentGroup) => removeUnreferencedComponentsInGroup(componentGroup, context)).filter(isDefined_default);
context.referencedTypes.components.clear();
if (newComponentGroups.length === 0) {
return void 0;
}
return ts3__default.default.factory.updateInterfaceDeclaration(
components,
components.modifiers,
components.name,
components.typeParameters,
components.heritageClauses,
newComponentGroups
);
}
__name(removeUnreferencedComponents, "removeUnreferencedComponents");
// src/utils/strings.ts
function convertToPascalCase(value) {
return value.replace(/(?:^|[^A-Za-z\d])([A-Za-z\d])/g, (_match, letter) => letter.toUpperCase());
}
__name(convertToPascalCase, "convertToPascalCase");
// ../zimic-utils/dist/data/isNonEmpty.mjs
function isNonEmpty(value) {
return isDefined_default(value) && value !== "";
}
__name(isNonEmpty, "isNonEmpty");
__name2(isNonEmpty, "isNonEmpty");
var isNonEmpty_default = isNonEmpty;
// ../zimic-utils/dist/url/createRegExpFromWildcardPath.mjs
function prepareURLForRegex(url) {
const encodedURL = encodeURI(url);
return encodedURL.replace(/([.()*?+$\\])/g, "\\$1");
}
__name(prepareURLForRegex, "prepareURLForRegex");
__name2(prepareURLForRegex, "prepareURLForRegex");
function createRegExpFromWildcardPath(path4, options) {
const pathWithReplacedWildcards = prepareURLForRegex(path4).replace(/^\/+|\/+$/g, "").replace(/\\\*/g, "*").replace(/\*\*\/\*/g, "**").replace(/(^|[^*])\*([^*]|$)/g, "$1[^/]*$2").replace(/\*\*/g, ".*");
return new RegExp(`^${options.prefix}/*${pathWithReplacedWildcards}/*$`);
}
__name(createRegExpFromWildcardPath, "createRegExpFromWildcardPath");
__name2(createRegExpFromWildcardPath, "createRegExpFromWildcardPath");
var createRegExpFromWildcardPath_default = createRegExpFromWildcardPath;
va