powershell/plugins/sdk-generate.ts (100 lines of code) (raw):

/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { values } from '@azure-tools/linq'; import { AutorestExtensionHost as Host } from '@autorest/extension-base'; import { join } from 'path'; import { CodeModel, ObjectSchema } from '@autorest/codemodel'; import { ModelState } from '../utils/model-state'; import { Project } from '../sdk/project'; import { OperationGroup } from '@autorest/codemodel'; import { getAllPublicVirtualProperties } from '@azure-tools/codemodel-v3'; const ejs = require('ejs'); const resources = `${__dirname}/../../resources`; async function generateModels(project: Project) { const path = join(join(resources, 'templates'), 'model.ejs'); for (const model of values(project.model.schemas.objects)) { if (model.extensions && (model.extensions['x-ms-client-flatten'] || model.extensions['x-ms-external']) || model.language.default.pagable) { // skip flattened model and pageble model continue; } const content = await ejs.renderFile(path, { model: model, project: project }); project.state.writeFile(`${project.baseFolder}\\Models\\${model.language.default.name}.cs`, content, undefined, 'source-file-csharp'); } } async function generateEnums(project: Project) { const path = join(join(resources, 'templates'), 'enum.ejs'); for (const model of values(project.model.schemas.sealedChoices)) { const content = await ejs.renderFile(path, { model: model, project: project }); project.state.writeFile(`${project.baseFolder}\\Models\\${model.language.default.name}.cs`, content, undefined, 'source-file-csharp'); } } async function generateMethodGroups(project: Project) { const path = join(join(resources, 'templates'), 'azureMethodGroup.ejs'); const interfacePath = join(join(resources, 'templates'), 'methodGroupInterface.ejs'); const extensionPath = join(join(resources, 'templates'), 'extensions.ejs'); for (const operationGroup of values(project.state.model.operationGroups)) { if (operationGroup.$key === '') { // for operations with no operation group, they will be added in the client class directly. const clientExtensionContent = await ejs.renderFile(extensionPath, { methodGroup: operationGroup, project: project, clientName: project.state.model.info.title }); project.state.writeFile(`${project.baseFolder}\\${project.state.model.info.title}Extensions.cs`, clientExtensionContent, undefined, 'source-file-csharp'); continue; } // generate method group class const key = project.helper.ConvertToValidMethodGroupKey(operationGroup.$key); const content = await ejs.renderFile(path, { methodGroup: operationGroup, project: project }); project.state.writeFile(`${project.baseFolder}\\${key}Operations.cs`, content, undefined, 'source-file-csharp'); // generate method group interface const interfaceContent = await ejs.renderFile(interfacePath, { methodGroup: operationGroup, project: project }); project.state.writeFile(`${project.baseFolder}\\I${key}Operations.cs`, interfaceContent, undefined, 'source-file-csharp'); // generate method group extensions const extensionContent = await ejs.renderFile(extensionPath, { methodGroup: operationGroup, project: project, clientName: '' }); project.state.writeFile(`${project.baseFolder}\\${key}OperationsExtensions.cs`, extensionContent, undefined, 'source-file-csharp'); } } async function generateClient(project: Project) { const path = join(join(resources, 'templates'), 'azureServiceClient.ejs'); const content = await ejs.renderFile(path, { project: project }); project.state.writeFile(`${project.baseFolder}\\${project.state.model.info.title}.cs`, content, undefined, 'source-file-csharp'); } async function generateClientInterface(project: Project) { const path = join(join(resources, 'templates'), 'serviceClientInterface.ejs'); const content = await ejs.renderFile(path, { project: project }); project.state.writeFile(`${project.baseFolder}\\I${project.state.model.info.title}.cs`, content, undefined, 'source-file-csharp'); } async function generatePageClasses(project: Project) { for (const [key, value] of Object.entries(project.state.model.language.default.pageClasses)) { const path = join(join(resources, 'templates'), 'page.ejs'); const className = value; const nextLinkName = key.split(' ')[0]; const itemName = key.split(' ')[1]; const page = { className: className, nextLinkName: nextLinkName, itemName: itemName }; const content = await ejs.renderFile(path, { project: project, page: page }); project.state.writeFile(`${project.baseFolder}\\Models\\${page.className}.cs`, content, undefined, 'source-file-csharp'); } } async function generateExceptions(project: Project) { const processedException = new Set(); const path = join(join(resources, 'templates'), 'exception.ejs'); for (const operationGroup of values(project.state.model.operationGroups)) { for (const operation of values(operationGroup.operations)) { if (operation.exceptions && (<any>operation.exceptions[0]).schema) { const exception = operation.exceptions[0]; if (processedException.has((<any>exception).schema) || ((<any>exception).schema.extensions && (<any>exception).schema.extensions['x-ms-external'])) { continue; } else { processedException.add((<any>exception).schema); } const content = await ejs.renderFile(path, { project: project, exception: exception }); project.state.writeFile(`${project.baseFolder}\\Models\\${(<any>exception).schema.language.default.name}Exception.cs`, content, undefined, 'source-file-csharp'); } } } } export async function generate(service: Host) { try { const project = await new Project(service).init(); await generateClient(project); await generateClientInterface(project); await generateMethodGroups(project); await generateModels(project); await generateEnums(project); await generatePageClasses(project); await generateExceptions(project); } catch (E) { console.error(`${__filename} - FAILURE ${JSON.stringify(E)}`); throw E; } }