Skip to content

Commit

Permalink
initial operations
Browse files Browse the repository at this point in the history
  • Loading branch information
mane-dev committed Sep 26, 2023
1 parent 6ab0de1 commit 9056c0d
Show file tree
Hide file tree
Showing 14 changed files with 341 additions and 551 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { join } from "path";
import { getSession } from "../autorest-session";
import { generateArmOperations } from "../generate/generate-arm-operations";
import { generateObject } from "../generate/generate-object";
import { CadlProgram } from "../interfaces";
import { ArmResourcesCache } from "../transforms/transform-resources";
Expand All @@ -13,7 +14,16 @@ export function emitArmResources(program: CadlProgram, basePath: string) {
const { modules, namespaces } = getResourcesImports(program);
const filePath = join(basePath, `${armResource.name}.tsp`);
const generatedResource = generateObject(armResource);
const content = [modules.join("\n"), "\n", namespaces.join("\n"), "\n", generatedResource].join("\n");
const armOperations = generateArmOperations(armResource);
const content = [
modules.join("\n"),
"\n",
namespaces.join("\n"),
"\n",
generatedResource,
"\n",
armOperations.join("\n"),
].join("\n");
session.writeFile({ filename: filePath, content: formatCadlFile(content, filePath) });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Operation, Schema, SchemaResponse, isObjectSchema } from "@autorest/codemodel";
import { lowerFirst } from "lodash";
import { plural } from "pluralize";
import { getSession } from "../autorest-session";
import { CadlObject, CadlObjectProperty, CadlOperation, TypespecArmResource } from "../interfaces";
import { transformOperation } from "../transforms/transform-operations";
import { ArmResourcesCache, getArmResourceNames } from "../transforms/transform-resources";
import { generateDecorators } from "../utils/decorators";
import { generateDocs } from "../utils/docs";
import { isArraySchema, isResponseSchema } from "../utils/schemas";

export function generateArmOperations(resource: TypespecArmResource) {
const definitions: string[] = [];
const codeModel = getSession().model;

const resourceOperationsKind = getResourceOperationsKind(resource);
definitions.push("@armResourceOperations");
definitions.push(
`interface ${plural(resource.name)} extends Azure.ResourceManager.${resourceOperationsKind}<${resource.name}, ${
resource.propertiesModelName
}>{`,
);

for (const operation of resource.operations) {
const typespecOperations = transformOperation(operation, codeModel).flatMap((p) => p);
for (const op of typespecOperations) {
definitions.push("@autoroute");
definitions.push(generateDocs(op));
definitions.push(`@armResourceLocation(${resource.name})`);
definitions.push(`@${op.verb}`);
definitions.push(
`${lowerFirst(op.name)}(${getOperationParameters(resource, op)}): ArmResponse<${getResponseType(
op,
operation,
)}> | ErrorResponse;`,
);
}
}
definitions.push("}");

return definitions;
}

function getOperationParameters(resource: TypespecArmResource, operation: CadlOperation) {
const params = [`...ResourceInstanceParameters<${resource.name}>`];

if (operation.extensions.includes("Pageable")) {
params.push(`...ListQueryParameters`);
}

return params.join(", ");
}

function getResponseType(operation: CadlOperation, rawOperation: Operation) {
const responseTypes = operation.responses.join(" |");
if (operation.extensions.includes("Pageable")) {
const armResourceNames = getArmResourceNames();

if (!isResultResourceList(rawOperation)) {
return `Page<${responseTypes}>`;
}

return `ResourceListResult<${operation.responses[0]}>`;
}

return responseTypes;
}

function isResultResourceList(operation: Operation) {
if (!operation.responses) {
return false;
}

if (!operation.responses[0]) {
return false;
}

const response = operation.responses[0];

if (!isResponseSchema(response)) {
return false;
}

if (!isObjectSchema(response.schema)) {
return false;
}

const values = response.schema.properties?.find((p) => p.serializedName === "value");

if (!values) {
return false;
}

if (!isArraySchema(values.schema)) {
return false;
}

const resultName = values.schema.elementType.language.default.name;
const resources = getArmResourceNames();

return resources.has(resultName);
}

function getResourceOperationsKind(resource: TypespecArmResource) {
switch (resource.resourceKind) {
case "ProxyResource":
return "ProxyResourceOperations";
case "TrackedResource":
return "TrackedResourceOperations";
default:
throw new Error(`Generating operations for ${resource.resourceKind} is not yet supported`);
}
}
3 changes: 2 additions & 1 deletion packages/extensions/openapi-to-cadl/src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ObjectSchema } from "@autorest/codemodel";
import { ObjectSchema, Operation } from "@autorest/codemodel";

export interface CadlProgram {
models: Models;
Expand Down Expand Up @@ -145,6 +145,7 @@ export interface TypespecArmResource extends CadlObject {
resourceKind: ArmResourceKind;
propertiesModelName: string;
path: string;
operations: Operation[];
schema: ObjectSchema;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function transformRequest(_request: Request, operation: Operation, codeModel: Co
verb: transformVerb(requests?.[0].protocol),
route: transformRoute(requests?.[0].protocol),
responses: [...new Set(transformedResponses)],
extensions: [],
extensions,
resource,
};
}
Expand Down
Loading

0 comments on commit 9056c0d

Please sign in to comment.