@autorest/openapi-to-typespec
Version:
Autorest plugin to scaffold a Typespec definition from an OpenAPI document
192 lines • 8.67 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateOperationGroupExamples = exports.generateOperationGroup = exports.generateParameters = exports.generateProviderAction = exports.generateOperation = void 0;
const options_1 = require("../options");
const decorators_1 = require("../utils/decorators");
const docs_1 = require("../utils/docs");
const lro_1 = require("../utils/lro");
const suppressions_1 = require("../utils/suppressions");
const generate_arm_resource_1 = require("./generate-arm-resource");
const generate_parameter_1 = require("./generate-parameter");
function generateOperation(operation, operationGroup) {
var _a;
const { isArm } = (0, options_1.getOptions)();
const doc = (0, docs_1.generateDocs)(operation);
const summary = (0, docs_1.generateSummary)(operation);
const { verb, name, route, parameters } = operation;
const params = generateParameters(parameters);
const statements = [];
summary && statements.push(summary);
statements.push(doc);
const modelResponses = [...new Set(operation.responses.filter((r) => r[1] !== "void").map((r) => r[1]))];
generateMultiResponseWarning(modelResponses, statements);
for (const fixme of (_a = operation.fixMe) !== null && _a !== void 0 ? _a : []) {
statements.push(fixme);
}
if (operation.decorators) {
statements.push((0, decorators_1.generateDecorators)(operation.decorators));
}
if (isArm) {
statements.push(`@route("${route}")`);
const otherResponses = operation.responses
.filter((r) => r[1] === "void" && ["200", "202"].includes(r[0]))
.map((r) => {
if (r[0] === "200")
return "OkResponse";
if (r[0] === "202")
return "ArmAcceptedResponse";
});
statements.push(`@${verb} op \`${name}\`(
...ApiVersionParameter,
${params}
): ${modelResponses.length > 0 ? `ArmResponse<${modelResponses.join(" | ")}>` : ""}${otherResponses.length > 0 ? `| ${otherResponses.join("|")}` : ""} | ErrorResponse;\n\n\n`);
}
else if (!operation.resource) {
const names = [name, ...modelResponses, ...parameters.map((p) => p.name)];
const duplicateNames = findDuplicates(names);
generateNameCollisionWarning(duplicateNames, statements);
statements.push(`@route("${route}")`);
statements.push(`@${verb} op \`${name}\` is Azure.Core.Foundations.Operation<${params ? params : "{}"}, ${modelResponses.length > 0 ? `${modelResponses.join(" | ")}` : "void"}>;\n\n\n`);
}
else {
const { resource } = operation;
const names = [name, ...modelResponses, ...parameters.map((p) => p.name)];
const duplicateNames = findDuplicates(names);
generateNameCollisionWarning(duplicateNames, statements);
const resourceParameters = generateParameters(parameters.filter((param) => !["path", "body"].some((p) => p === param.location)));
const parametersString = resourceParameters ? `, { parameters: ${resourceParameters}}` : "";
statements.push(`${(operationGroup === null || operationGroup === void 0 ? void 0 : operationGroup.name) ? "" : "op "}`, `\`${name}\` is Azure.Core.${resource.kind}<${resource.response.name} ${parametersString}>;\n\n\n`);
}
return statements.join("\n");
}
exports.generateOperation = generateOperation;
function generateProviderAction(operation) {
const doc = (0, docs_1.generateDocs)(operation);
const summary = (0, docs_1.generateSummary)(operation);
const statements = [];
summary && statements.push(summary);
statements.push(doc);
const templateParameters = [];
if (operation.request) {
templateParameters.push(`Request = ${operation.request.type}`);
}
if (operation.response) {
if (operation.response.endsWith("[]")) {
templateParameters.push(`Response = {@bodyRoot _: ${operation.response}}`);
}
else {
templateParameters.push(`Response = ${operation.response}`);
}
}
if (operation.scope) {
templateParameters.push(`Scope = ${operation.scope}`);
}
if (operation.parameters.length > 0) {
const params = [];
for (const parameter of operation.parameters) {
if (parameter.name === "subscriptionId")
continue;
if (parameter.name === "location") {
params.push("...LocationParameter");
}
else {
params.push((0, generate_parameter_1.generateParameter)(parameter));
}
}
if (params.length === 1 && params[0] === "...LocationParameter") {
templateParameters.push(`Parameters = LocationParameter`);
}
else {
templateParameters.push(`Parameters = {${params}}`);
}
}
if (operation.lroHeaders) {
templateParameters.push(`LroHeaders = ${(0, lro_1.generateLroHeaders)(operation.lroHeaders)}`);
}
if (operation.suppressions) {
statements.push((0, suppressions_1.generateSuppressions)(operation.suppressions).join("\n"));
}
if (operation.decorators) {
statements.push((0, decorators_1.generateDecorators)(operation.decorators));
}
if (operation.verb) {
statements.push(`@${operation.verb}`);
}
if (operation.action) {
statements.push(`@action("${operation.action}")`);
}
statements.push(`${operation.name} is ${operation.kind}<${(templateParameters !== null && templateParameters !== void 0 ? templateParameters : []).join(",")}>`);
return statements.join("\n");
}
exports.generateProviderAction = generateProviderAction;
function findDuplicates(arr) {
return arr.filter((item, index) => arr.indexOf(item) != index);
}
function generateNameCollisionWarning(duplicateNames, statements) {
if (!duplicateNames.length) {
return;
}
const unique = [...new Set(duplicateNames)];
const message = `// FIXME: (name-collision-error) There is a potential collision with Operation, Parameter and Response names.
// Problematic names: [${unique.join()}]`;
statements.push(message);
}
function generateMultiResponseWarning(responses, statements) {
responses.length > 2 &&
statements.push(`// FIXME: (multi-response) Swagger defines multiple requests and responses.
// This needs to be revisited as Typespec supports linking specific responses to each request`);
}
function generateParameters(parameters) {
const { isArm } = (0, options_1.getOptions)();
if (parameters.length === 0) {
return "";
}
if (parameters.length === 1 && parameters[0].location === "body") {
if (parameters[0].type === "unknown") {
return "unknown";
}
else {
return parameters[0].type;
}
}
const params = [];
for (const parameter of parameters) {
params.push((0, generate_parameter_1.generateParameter)(parameter));
}
if (isArm) {
return `${params.join(",\n")}`;
}
return `{${params.join("\n")}}`;
}
exports.generateParameters = generateParameters;
function generateOperationGroup(operationGroup) {
const statements = [];
const doc = (0, docs_1.generateDocs)(operationGroup);
const { name, operations } = operationGroup;
statements.push(`${doc}`);
operationGroup.suppressions && statements.push((0, suppressions_1.generateSuppressions)(operationGroup.suppressions).join("\n"));
const hasInterface = Boolean(name);
hasInterface && statements.push(`interface ${name} {`);
for (const operation of operations) {
if (operation.kind !== undefined) {
statements.push(generateProviderAction(operation));
}
else {
statements.push(generateOperation(operation, operationGroup));
}
}
hasInterface && statements.push(`}`);
return statements.join("\n");
}
exports.generateOperationGroup = generateOperationGroup;
function generateOperationGroupExamples(operationGroup) {
var _a, _b;
const examples = {};
const { name, operations } = operationGroup;
for (const operation of operations) {
(0, generate_arm_resource_1.generateExamples)((_a = operation.examples) !== null && _a !== void 0 ? _a : {}, (_b = operation.operationId) !== null && _b !== void 0 ? _b : (0, generate_arm_resource_1.getGeneratedOperationId)(name, operation.name), examples);
}
return examples;
}
exports.generateOperationGroupExamples = generateOperationGroupExamples;
//# sourceMappingURL=generate-operations.js.map
;