@autorest/openapi-to-cadl
Version:
Autorest plugin to scaffold a Typespec definition from an OpenAPI document
164 lines • 6.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformParameter = exports.transformOperation = exports.transformOperationGroup = void 0;
const codemodel_1 = require("@autorest/codemodel");
const data_types_1 = require("../data-types");
const model_1 = require("../model");
const logger_1 = require("../utils/logger");
const metadata_1 = require("../utils/metadata");
const schemas_1 = require("../utils/schemas");
function transformOperationGroup({ language, operations }, codeModel) {
const name = language.default.name ? `${language.default.name}Operations` : "";
const doc = language.default.description;
const ops = operations.reduce((acc, op) => {
acc = [...acc, ...transformOperation(op, codeModel)];
return acc;
}, []);
return {
name,
doc,
operations: ops,
};
}
exports.transformOperationGroup = transformOperationGroup;
function transformRoute(protocol) {
var _a;
return (_a = protocol === null || protocol === void 0 ? void 0 : protocol.http) === null || _a === void 0 ? void 0 : _a.path;
}
function transformVerb(protocol) {
var _a;
return (_a = protocol === null || protocol === void 0 ? void 0 : protocol.http) === null || _a === void 0 ? void 0 : _a.method;
}
function transformResponses(responses = [], codeModel) {
const dataTypes = (0, data_types_1.getDataTypes)(codeModel);
return responses.map(({ schema }) => {
var _a, _b;
const responseName = (_a = dataTypes.get(schema)) === null || _a === void 0 ? void 0 : _a.name;
if (!responseName) {
return "void";
}
if (((_b = schema.language.default.paging) === null || _b === void 0 ? void 0 : _b.isPageable) && schema.language.default.resource) {
return `Azure.Core.ResourceList<${responseName}>`;
}
return responseName;
});
}
function transformOperation(operation, codeModel) {
var _a;
return ((_a = operation.requests) !== null && _a !== void 0 ? _a : []).map((r) => transformRequest(r, operation, codeModel));
}
exports.transformOperation = transformOperation;
function transformRequest(_request, operation, codeModel) {
var _a;
const { language, responses, requests } = operation;
const name = language.default.name;
const doc = language.default.description;
const summary = language.default.summary;
const { paging } = (0, metadata_1.getLanguageMetadata)(operation.language);
const transformedResponses = transformResponses([...(responses !== null && responses !== void 0 ? responses : [])], codeModel);
const visitedParameter = new Set();
let parameters = ((_a = operation.parameters) !== null && _a !== void 0 ? _a : [])
.filter((p) => filterOperationParameters(p, visitedParameter))
.map((v) => transformParameter(v, codeModel));
parameters = [
...parameters,
...getRequestParameters(operation)
.filter((p) => filterOperationParameters(p, visitedParameter))
.map((v) => transformParameter(v, codeModel)),
];
const extensions = [];
if (paging) {
extensions.push("Pageable");
}
const resource = operation.language.default.resource;
return {
name,
doc,
summary,
parameters,
verb: transformVerb(requests === null || requests === void 0 ? void 0 : requests[0].protocol),
route: transformRoute(requests === null || requests === void 0 ? void 0 : requests[0].protocol),
responses: [...new Set(transformedResponses)],
extensions: [],
resource,
};
}
function constantValueEquals(schema, match) {
if ((0, schemas_1.isConstantSchema)(schema)) {
const value = schema.value.value;
if (typeof value === "string") {
return value.toLowerCase() === match.toLowerCase();
}
}
return false;
}
function filterOperationParameters(parameter, visitedParameters) {
var _a, _b;
if (((_a = parameter.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === codemodel_1.ParameterLocation.Query &&
parameter.language.default.serializedName === "api-version") {
return false;
}
if (parameter.origin === "modelerfour:synthesized/accept" &&
constantValueEquals(parameter.schema, "application/json")) {
return false;
}
if (visitedParameters.has(parameter)) {
return false;
}
const shouldVisit = ["path", "body", "header", "query"].includes((_b = parameter.protocol.http) === null || _b === void 0 ? void 0 : _b.in);
if (shouldVisit) {
visitedParameters.add(parameter);
}
return shouldVisit;
}
function transformParameter(parameter, codeModel) {
var _a, _b;
// Body parameter doesn't have a serializedName, in that case we get the name
const name = (_a = parameter.language.default.serializedName) !== null && _a !== void 0 ? _a : parameter.language.default.name;
const doc = parameter.language.default.description;
const dataTypes = (0, data_types_1.getDataTypes)(codeModel);
const visited = (_b = dataTypes.get(parameter.schema)) !== null && _b !== void 0 ? _b : (0, model_1.transformDataType)(parameter.schema, codeModel);
return {
kind: "parameter",
doc,
name,
isOptional: parameter.required !== true,
type: visited.name,
location: transformParameterLocation(parameter),
};
}
exports.transformParameter = transformParameter;
function getRequestParameters(operation) {
var _a, _b, _c;
const logger = (0, logger_1.getLogger)("getRequestParameters");
if (!((_a = operation.requests) === null || _a === void 0 ? void 0 : _a.length)) {
return [];
}
if (operation.requests.length > 1) {
const message = `Operation ${operation.language.default.name} has more than one request`;
logger.info(message);
}
const parameters = (_b = operation.requests[0].parameters) !== null && _b !== void 0 ? _b : [];
const signatureParameters = (_c = operation.requests[0].signatureParameters) !== null && _c !== void 0 ? _c : [];
return [...parameters, ...signatureParameters];
}
function transformParameterLocation(parameter) {
var _a;
const location = (_a = parameter.protocol.http) === null || _a === void 0 ? void 0 : _a.in;
if (!location) {
throw new Error(`Parameter ${parameter.language.default.name} has no location defined`);
}
switch (location) {
case codemodel_1.ParameterLocation.Path:
return "path";
case codemodel_1.ParameterLocation.Query:
return "query";
case codemodel_1.ParameterLocation.Header:
return "header";
case codemodel_1.ParameterLocation.Body:
return "body";
default:
throw new Error(`Unknown location ${location}`);
}
}
//# sourceMappingURL=transform-operations.js.map