UNPKG

@microsoft.azure/autorest.incubator

Version:
293 lines 16.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const project_1 = require("../csharp/code-dom/project"); const schema_1 = require("../common/code-model/schema"); const dictionary_1 = require("../common/dictionary"); const access_modifier_1 = require("../csharp/code-dom/access-modifier"); const attribute_1 = require("../csharp/code-dom/attribute"); const class_1 = require("../csharp/code-dom/class"); const expression_1 = require("../csharp/code-dom/expression"); const import_1 = require("../csharp/code-dom/import"); const interface_1 = require("../csharp/code-dom/interface"); const method_1 = require("../csharp/code-dom/method"); const dotnet = require("../csharp/code-dom/mscorlib"); const namespace_1 = require("../csharp/code-dom/namespace"); const parameter_1 = require("../csharp/code-dom/parameter"); const if_1 = require("../csharp/code-dom/statements/if"); const return_1 = require("../csharp/code-dom/statements/return"); const try_1 = require("../csharp/code-dom/statements/try"); const clientruntime_1 = require("../csharp/lowlevel-generator/clientruntime"); const object_1 = require("../csharp/schema/object"); const schema_resolver_1 = require("../csharp/schema/schema-resolver"); const model_cmdlet_1 = require("../powershell/model-cmdlet"); const module_class_1 = require("../powershell/module-class"); const powershell_declarations_1 = require("../powershell/powershell-declarations"); const cmdlet_class_1 = require("./cmdlet-class"); const text_manipulation_1 = require("../common/text-manipulation"); class ServiceNamespace extends namespace_1.Namespace { constructor(state, objectInitializer) { super(state.model.details.csharp.namespace || 'INVALID.NAMESPACE', state.project); this.state = state; this.apply(objectInitializer); // module class this.moduleClass = new module_class_1.ModuleClass(this, state); } get outputFolder() { return this.state.project.moduleFolder; } } exports.ServiceNamespace = ServiceNamespace; class ModelExtensionsNamespace extends namespace_1.Namespace { constructor(parent, schemas, state, objectInitializer) { super('Models', parent); this.schemas = schemas; this.state = state; this.resolver = new schema_resolver_1.SchemaDefinitionResolver(); this.apply(objectInitializer); const $this = this; // Add typeconverters to model classes (partial) for (const { key: schemaName, value: schema } of dictionary_1.items(schemas)) { if (!schema) { continue; } const td = this.resolver.resolveTypeDeclaration(schema, true, state); if (td instanceof object_1.ObjectImplementation) { // it's a class object. const className = td.schema.details.csharp.name; const interfaceName = td.schema.details.csharp.interfaceName || ''; const converterClass = `${className}TypeConverter`; // create the model extensions for each object model // 2. A partial interface with the type converter attribute const modelInterface = new interface_1.Interface(this, interfaceName, { partial: true, }); modelInterface.add(new attribute_1.Attribute(powershell_declarations_1.TypeConverterAttribute, { parameters: [new expression_1.LiteralExpression(`typeof(${converterClass})`)] })); // 1. A partial class with the type converter attribute const model = new class_1.Class(this, className, undefined, { partial: true, }); model.add(new attribute_1.Attribute(powershell_declarations_1.TypeConverterAttribute, { parameters: [new expression_1.LiteralExpression(`typeof(${converterClass})`)] })); model.add(new method_1.LambdaMethod('FromJsonString', modelInterface, new expression_1.LiteralExpression(`FromJson(${clientruntime_1.ClientRuntime.JsonNode.declaration}.Parse(jsonText))`), { static: access_modifier_1.Modifier.Static, parameters: [new parameter_1.Parameter('jsonText', dotnet.String)] })); model.add(new method_1.LambdaMethod('ToJsonString', dotnet.String, new expression_1.LiteralExpression(`ToJson(${dotnet.Null}, ${clientruntime_1.ClientRuntime.SerializationMode.IncludeAll})?.ToString(System.Globalization.CultureInfo.InvariantCulture)`), {})); // + static <interfaceType> FromJsonString(string json); // + string ToJsonString() // 3. A TypeConverter class const typeConverter = new class_1.Class(this, converterClass, powershell_declarations_1.PSTypeConverter); typeConverter.add(new method_1.LambdaMethod('CanConvertTo', dotnet.Bool, dotnet.False, { override: access_modifier_1.Modifier.Override, parameters: [ new parameter_1.Parameter('sourceValue', dotnet.Object), new parameter_1.Parameter('destinationType', dotnet.System.Type) ] })); typeConverter.add(new method_1.LambdaMethod('ConvertTo', dotnet.Object, dotnet.Null, { override: access_modifier_1.Modifier.Override, parameters: [ new parameter_1.Parameter('sourceValue', dotnet.Object), new parameter_1.Parameter('destinationType', dotnet.System.Type), new parameter_1.Parameter('formatProvider', dotnet.System.IFormatProvider), new parameter_1.Parameter('ignoreCase', dotnet.Bool), ] })); typeConverter.add(new method_1.LambdaMethod('CanConvertFrom', dotnet.Bool, new expression_1.LiteralExpression(`CanConvertFrom(sourceValue)`), { override: access_modifier_1.Modifier.Override, parameters: [ new parameter_1.Parameter('sourceValue', dotnet.Object), new parameter_1.Parameter('destinationType', dotnet.System.Type) ] })); typeConverter.add(new method_1.LambdaMethod('ConvertFrom', dotnet.Object, new expression_1.LiteralExpression('ConvertFrom(sourceValue)'), { override: access_modifier_1.Modifier.Override, parameters: [ new parameter_1.Parameter('sourceValue', dotnet.Object), new parameter_1.Parameter('destinationType', dotnet.System.Type), new parameter_1.Parameter('formatProvider', dotnet.System.IFormatProvider), new parameter_1.Parameter('ignoreCase', dotnet.Bool), ] })); typeConverter.add(new method_1.Method('CanConvertFrom', dotnet.Bool, { static: access_modifier_1.Modifier.Static, parameters: [ new parameter_1.Parameter('sourceValue', dotnet.Dynamic), ] })).add(function* () { yield if_1.If(`null == sourceValue`, return_1.Return(dotnet.True)); yield try_1.Try(function* () { yield if_1.If(`sourceValue.GetType() == typeof(${powershell_declarations_1.PSObject.declaration})`, function* () { yield `// does it have the properties we need`; }); yield if_1.ElseIf(`sourceValue.GetType() == typeof(${dotnet.System.Collections.Hashtable.declaration})`, function* () { yield `// a hashtable?`; }); yield if_1.Else(function* () { yield `// object `; }); // is the source a PSType or a hashtable? // is the source a string? has a ToJson? // try deserializing, and validate. if successful, return true // does it have the same members as I do? }); yield try_1.Catch(undefined, `// Unable to use JSON pattern`); yield return_1.Return(dotnet.False); }); typeConverter.add(new method_1.Method('ConvertFrom', dotnet.Object, { static: access_modifier_1.Modifier.Static, parameters: [ new parameter_1.Parameter('sourceValue', dotnet.Dynamic), ] })).add(function* () { // null begets null yield if_1.If(`null == sourceValue`, return_1.Return(dotnet.Null)); // try using json first (either from string or toJsonString()) yield try_1.Try(`${className}.FromJsonString(typeof(string) == sourceValue.GetType() ? sourceValue : sourceValue.ToJsonString());`); yield try_1.Catch(undefined, `// Unable to use JSON pattern`); yield try_1.Try(function* () { yield `return new ${className}`; yield `{`; // loop thru members... for (const member of dictionary_1.values(td.schema.properties)) { // if it's a primitive field const memTD = $this.resolver.resolveTypeDeclaration(member.schema, true, state); if (memTD instanceof object_1.ObjectImplementation) { // it's an object, try the typeconverter yield `${member.details.csharp.name} = ${member.schema.details.csharp.name}TypeConverter.ConvertFrom(sourceValue.${member.details.csharp.name}),`; } else { // just assign it. yield `${member.details.csharp.name} = sourceValue.${member.details.csharp.name},`; } // otherwise use the field's typeconverter } yield `};`; }); yield try_1.Catch(undefined, ``); // null if not successful yield return_1.Return(dotnet.Null); }); } } } get outputFolder() { return this.state.project.apiextensionsfolder; } } exports.ModelExtensionsNamespace = ModelExtensionsNamespace; class ModelCmdletNamespace extends namespace_1.Namespace { constructor(parent, state, objectInitializer) { super('ModelCmdlets', parent); this.state = state; this.inputModels = new Array(); this.apply(objectInitializer); this.addUsing(new import_1.Import('static Microsoft.Rest.ClientRuntime.IEventListenerExtensions')); this.addUsing(new import_1.Import('static Microsoft.Rest.ClientRuntime.HttpRequestMessageExtensions')); } get outputFolder() { return this.state.project.modelCmdletFolder; } createModelCmdlets() { // generate the model cmdlets unless they dont want them. if (!this.state.project.skipModelCmdlets) { for (const { key: id, value: schema } of dictionary_1.items(this.state.model.schemas)) { if (schema.type !== schema_1.JsonType.Object) { continue; } let found = false; // check if a cmdlet uses this as a parameter for (const sch of dictionary_1.values(this.inputModels)) { if (sch === schema) { found = true; break; } } if (found) { this.addClass(new model_cmdlet_1.ModelCmdlet(this, schema, this.state.path('schemas', id))); } } } } addInputSchema(schema) { if (schema.type === schema_1.JsonType.Object) { if (this.inputModels.indexOf(schema) === -1) { this.inputModels.push(schema); for (const p of dictionary_1.values(schema.properties)) { if (!p.schema.readOnly && !p.details.csharp.HeaderProperty && !p.schema.additionalProperties) { this.addInputSchema(p.schema); } } } } } } exports.ModelCmdletNamespace = ModelCmdletNamespace; class CmdletNamespace extends namespace_1.Namespace { constructor(parent, state, objectInitializer) { super('Cmdlets', parent); this.state = state; this.inputModels = new Array(); this.apply(objectInitializer); this.addUsing(new import_1.Import('static Microsoft.Rest.ClientRuntime.IEventListenerExtensions')); this.addUsing(new import_1.Import('static Microsoft.Rest.ClientRuntime.HttpRequestMessageExtensions')); // generate cmdlet classes on top of the SDK for (const { key: id, value: operation } of dictionary_1.items(state.model.commands.operations)) { this.addClass(new cmdlet_class_1.CmdletClass(this, operation, state.path('commands', 'operations', id))); if (operation.details.powershell.hasBody) { // make a copy that doesn't use the body parameter this.addClass(new cmdlet_class_1.CmdletClass(this, operation, state.path('commands', 'operations', id), true)); } for (const p of operation.parameters) { state.project.modelCmdlets.addInputSchema(p.schema); } } } get outputFolder() { return this.state.project.cmdletFolder; } } exports.CmdletNamespace = CmdletNamespace; class Project extends project_1.Project { constructor(state) { super(); this.state = state; this.schemaDefinitionResolver = new schema_resolver_1.SchemaDefinitionResolver(); state.project = this; } async init() { await super.init(); const service = this.state.service; const model = this.state.model; const state = this.state; const mil = await service.GetValue('max-inlined-parameters'); this.maxInlinedParameters = typeof mil === 'number' ? mil : 4; const smc = await service.GetValue('skip-model-cmdlets'); this.skipModelCmdlets = smc ? true : false; this.azure = await service.GetValue('azure') || await service.GetValue('azure-arm') || false; this.moduleName = text_manipulation_1.pascalCase(text_manipulation_1.deconstruct(await service.GetValue('module-name') || model.info.title.replace(/client/ig, ''))); this.moduleFolder = await service.GetValue('module-folder') || './private'; this.cmdletFolder = await service.GetValue('cmdlet-folder') || `${this.moduleFolder}/cmdlets/generated`; this.modelCmdletFolder = await service.GetValue('model-cmdlet-folder') || `${this.moduleFolder}/cmdlets/models`; this.customFolder = await service.GetValue('custom-cmdlet-folder') || `${this.moduleFolder}/cmdlets/custom`; this.runtimefolder = await service.GetValue('runtime-folder') || `${this.moduleFolder}/runtime`; this.apifolder = await service.GetValue('api-folder') || `${this.moduleFolder}/api`; this.apiextensionsfolder = await service.GetValue('api-extensions-folder') || `${this.moduleFolder}/api-extensions`; this.csproj = await service.GetValue('csproj') || `${this.moduleName}.private.csproj`; this.psd1 = await service.GetValue('psd1') || `${this.moduleName}.psd1`; this.psm1 = await service.GetValue('psm1') || `${this.moduleName}.psm1`; // add project namespace this.addNamespace(this.serviceNamespace = new ServiceNamespace(state)); this.addNamespace(this.modelCmdlets = new ModelCmdletNamespace(this.serviceNamespace, state)); // add cmdlet namespace this.addNamespace(this.cmdlets = new CmdletNamespace(this.serviceNamespace, state)); this.addNamespace(this.modelsExtensions = new ModelExtensionsNamespace(this.serviceNamespace, state.model.schemas, state.path('components', 'schemas'))); if (!this.skipModelCmdlets) { this.modelCmdlets.createModelCmdlets(); } // abort now if we have any errors. state.checkpoint(); return this; } } exports.Project = Project; //# sourceMappingURL=project.js.map