UNPKG

@autorest/powershell

Version:
721 lines 171 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.CmdletClass = exports.NewAddInfoAttribute = exports.addInfoAttribute = exports.addDefaultInfo = exports.addParameterPreviewMessage = exports.addParameterBreakingChange = exports.addPSArgumentCompleterAttribute = exports.isEnumImplementation = exports.NewAddCompleterInfo = exports.addCompleterInfo = exports.createStepper = void 0; const ejs = require('ejs'); const codemodel_1 = require("@autorest/codemodel"); const codemodel_v3_1 = require("@azure-tools/codemodel-v3"); const command_operation_1 = require("../utils/command-operation"); const schema_1 = require("../utils/schema"); const codegen_1 = require("@azure-tools/codegen"); const linq_1 = require("@azure-tools/linq"); const codegen_csharp_1 = require("@azure-tools/codegen-csharp"); const exports_1 = require("../llcsharp/exports"); const powershell_declarations_1 = require("../internal/powershell-declarations"); const extension_base_1 = require("@autorest/extension-base"); const codegen_csharp_2 = require("@azure-tools/codegen-csharp"); const model_class_1 = require("../llcsharp/model/model-class"); const resourceName_1 = require("../utils/resourceName"); const PropertiesRequiringNew = new Set(['Host', 'Events']); const Verbs = { Common: 'global::System.Management.Automation.VerbsCommon', Data: 'global::System.Management.Automation.VerbsData', Lifecycle: 'global::System.Management.Automation.VerbsLifecycle', Diagnostic: 'global::System.Management.Automation.VerbsDiagnostic', Communications: 'global::System.Management.Automation.VerbsCommunications', Security: 'global::System.Management.Automation.VerbsSecurity', Other: 'global::System.Management.Automation.VerbsOther' }; const category = { 'Add': Verbs.Common, 'Clear': Verbs.Common, 'Close': Verbs.Common, 'Copy': Verbs.Common, 'Enter': Verbs.Common, 'Exit': Verbs.Common, 'Find': Verbs.Common, 'Format': Verbs.Common, 'Get': Verbs.Common, 'Hide': Verbs.Common, 'Join': Verbs.Common, 'Lock': Verbs.Common, 'Move': Verbs.Common, 'New': Verbs.Common, 'Open': Verbs.Common, 'Optimize': Verbs.Common, 'Pop': Verbs.Common, 'Push': Verbs.Common, 'Redo': Verbs.Common, 'Remove': Verbs.Common, 'Rename': Verbs.Common, 'Reset': Verbs.Common, 'Resize': Verbs.Common, 'Search': Verbs.Common, 'Select': Verbs.Common, 'Set': Verbs.Common, 'Show': Verbs.Common, 'Skip': Verbs.Common, 'Split': Verbs.Common, 'Step': Verbs.Common, 'Switch': Verbs.Common, 'Undo': Verbs.Common, 'Unlock': Verbs.Common, 'Watch': Verbs.Common, 'Backup': Verbs.Data, 'Checkpoint': Verbs.Data, 'Compare': Verbs.Data, 'Compress': Verbs.Data, 'Convert': Verbs.Data, 'ConvertFrom': Verbs.Data, 'ConvertTo': Verbs.Data, 'Dismount': Verbs.Data, 'Edit': Verbs.Data, 'Expand': Verbs.Data, 'Export': Verbs.Data, 'Group': Verbs.Data, 'Import': Verbs.Data, 'Initialize': Verbs.Data, 'Limit': Verbs.Data, 'Merge': Verbs.Data, 'Mount': Verbs.Data, 'Out': Verbs.Data, 'Publish': Verbs.Data, 'Restore': Verbs.Data, 'Save': Verbs.Data, 'Sync': Verbs.Data, 'Unpublish': Verbs.Data, 'Update': Verbs.Data, 'Approve': Verbs.Lifecycle, 'Assert': Verbs.Lifecycle, 'Complete': Verbs.Lifecycle, 'Confirm': Verbs.Lifecycle, 'Deny': Verbs.Lifecycle, 'Disable': Verbs.Lifecycle, 'Enable': Verbs.Lifecycle, 'Install': Verbs.Lifecycle, 'Invoke': Verbs.Lifecycle, 'Register': Verbs.Lifecycle, 'Request': Verbs.Lifecycle, 'Restart': Verbs.Lifecycle, 'Resume': Verbs.Lifecycle, 'Start': Verbs.Lifecycle, 'Stop': Verbs.Lifecycle, 'Submit': Verbs.Lifecycle, 'Suspend': Verbs.Lifecycle, 'Uninstall': Verbs.Lifecycle, 'Unregister': Verbs.Lifecycle, 'Wait': Verbs.Lifecycle, 'Debug': Verbs.Diagnostic, 'Measure': Verbs.Diagnostic, 'Ping': Verbs.Diagnostic, 'Repair': Verbs.Diagnostic, 'Resolve': Verbs.Diagnostic, 'Test': Verbs.Diagnostic, 'Trace': Verbs.Diagnostic, 'Connect': Verbs.Communications, 'Disconnect': Verbs.Communications, 'Read': Verbs.Communications, 'Receive': Verbs.Communications, 'Send': Verbs.Communications, 'Write': Verbs.Communications, 'Block': Verbs.Security, 'Grant': Verbs.Security, 'Protect': Verbs.Security, 'Revoke': Verbs.Security, 'Unblock': Verbs.Security, 'Unprotect': Verbs.Security, 'Use': Verbs.Other, }; function createStepper(p) { return (0, codegen_csharp_1.toExpression)(`${codegen_csharp_1.System.Linq.Enumerable.declaration}.Select<${exports_1.ClientRuntime.SendAsyncStep.declaration},${exports_1.ClientRuntime.SendAsyncStep.declaration}>(${p.value}, step => (r, c, n) => { ${powershell_declarations_1.DefaultRunspace.value} = ${powershell_declarations_1.DefaultRunspace.value} ?? ${powershell_declarations_1.RunspaceFactory.declaration}.CreateRunspace(); return step(r, c, n); })`); } exports.createStepper = createStepper; function addCompleterInfo(targetProperty, parameter) { if (parameter.completerInfo && parameter.completerInfo.script) { targetProperty.add(new codegen_csharp_1.Attribute(exports_1.ClientRuntime.CompleterInfoAttribute, { parameters: [ new codegen_csharp_1.LiteralExpression(`\nName = ${new codegen_csharp_1.StringExpression(parameter.completerInfo.name || '').value}`), new codegen_csharp_1.LiteralExpression(`\nDescription =${new codegen_csharp_1.StringExpression(parameter.completerInfo.description || '').value}`), new codegen_csharp_1.LiteralExpression(`\nScript = ${new codegen_csharp_1.StringExpression(parameter.completerInfo.script).value}`) ] })); } } exports.addCompleterInfo = addCompleterInfo; function NewAddCompleterInfo(targetProperty, parameter) { if (parameter.completerInfo && parameter.completerInfo.script) { targetProperty.add(new codegen_csharp_1.Attribute(exports_1.ClientRuntime.CompleterInfoAttribute, { parameters: [ new codegen_csharp_1.LiteralExpression(`\nName = ${new codegen_csharp_1.StringExpression(parameter.completerInfo.name || '').value}`), new codegen_csharp_1.LiteralExpression(`\nDescription =${new codegen_csharp_1.StringExpression(parameter.completerInfo.description || '').value}`), new codegen_csharp_1.LiteralExpression(`\nScript = ${new codegen_csharp_1.StringExpression(parameter.completerInfo.script).value}`) ] })); } } exports.NewAddCompleterInfo = NewAddCompleterInfo; function isEnumImplementation(schema) { return ((schema === null || schema === void 0 ? void 0 : schema.type) === codemodel_1.SchemaType.SealedChoice && !schema.language.default.skip) || ((schema === null || schema === void 0 ? void 0 : schema.extensions) && schema.extensions['x-ms-enum']); } exports.isEnumImplementation = isEnumImplementation; function addPSArgumentCompleterAttribute(targetProperty, parameterSchema) { const enumValues = (0, linq_1.values)(parameterSchema.language.csharp.enum.values).select(v => `"${v.value}"`).toArray().join(', '); targetProperty.add(new codegen_csharp_1.Attribute(powershell_declarations_1.PSArgumentCompleterAttribute, { parameters: [`${enumValues}`] })); } exports.addPSArgumentCompleterAttribute = addPSArgumentCompleterAttribute; function addParameterBreakingChange(targetProperty, parameter) { if (parameter.breakingChange) { const parameters = []; parameters.push(`"${parameter.breakingChange.parameterName}"`); if (!parameter.breakingChange.deprecateByVersion || !parameter.breakingChange.deprecateByAzVersion) { throw new Error(`breakingChange.deprecateByVersion and breakingChange.deprecateByAzVersion must be set for ${parameter.name}`); } parameters.push(`"${parameter.breakingChange.deprecateByAzVersion}"`); parameters.push(`"${parameter.breakingChange.deprecateByVersion}"`); if (parameter.breakingChange.changeInEfectByDate) parameters.push(`"${parameter.breakingChange.changeInEfectByDate}"`); if (parameter.breakingChange.replacement) parameters.push(`ReplaceMentCmdletParameterName="${parameter.breakingChange.replacement}"`); if (parameter.breakingChange.isBecomingMandatory) parameters.push(`IsBecomingMandatory=${parameter.breakingChange.isBecomingMandatory}`); if (parameter.breakingChange.changeDescription) parameters.push(`ChangeDescription="${parameter.breakingChange.changeDescription}"`); if (parameter.breakingChange.newParameterType) { // If old type is set in directive, use it, otherwise try to get the type from the schema if (parameter.breakingChange.oldParamaterType) { parameters.push(`OldParamaterType="${parameter.breakingChange.oldParamaterType}"`); } else { // for primitive types, should use name, otherwise use fullname which contains namespace parameters.push(`OldParamaterType="${parameter.schema.language.csharp.fullname.startsWith('<') ? parameter.schema.language.csharp.name : parameter.schema.language.csharp.fullname}"`); } parameters.push(`NewParameterType="${parameter.breakingChange.newParameterType}"`); } targetProperty.add(new codegen_csharp_1.Attribute(exports_1.ClientRuntime.ParameterBreakingChangeAttribute, { parameters: parameters })); } } exports.addParameterBreakingChange = addParameterBreakingChange; function addParameterPreviewMessage(targetProperty, parameter) { if (parameter.previewAnnouncement) { const parameters = []; parameters.push(`"${parameter.previewAnnouncement.previewMessage}"`); if (parameter.previewAnnouncement.estimatedGaDate) parameters.push(`"${parameter.previewAnnouncement.estimatedGaDate}"`); targetProperty.add(new codegen_csharp_1.Attribute(exports_1.ClientRuntime.PreviewMessageAttribute, { parameters: parameters })); } } exports.addParameterPreviewMessage = addParameterPreviewMessage; function addDefaultInfo(targetProperty, parameter) { if (parameter.defaultInfo && parameter.defaultInfo.script) { targetProperty.add(new codegen_csharp_1.Attribute(exports_1.ClientRuntime.DefaultInfoAttribute, { parameters: [ new codegen_csharp_1.LiteralExpression(`\nName = ${new codegen_csharp_1.StringExpression(parameter.defaultInfo.name || '').value}`), new codegen_csharp_1.LiteralExpression(`\nDescription =${new codegen_csharp_1.StringExpression(parameter.defaultInfo.description || '').value}`), new codegen_csharp_1.LiteralExpression(`\nScript = ${new codegen_csharp_1.StringExpression(parameter.defaultInfo.script).value}`), new codegen_csharp_1.LiteralExpression(`\nSetCondition = ${new codegen_csharp_1.StringExpression(parameter.defaultInfo['set-condition'] || '').value}`) ] })); } } exports.addDefaultInfo = addDefaultInfo; function addInfoAttribute(targetProperty, pType, isRequired, isReadOnly, description, serializedName) { let pt = pType; while (pt.elementType) { switch (pt.elementType.schema.type) { case codemodel_v3_1.JsonType.Object: if (pt.elementType.schema.details.csharp.interfaceImplementation) { pt = { declaration: pt.elementType.schema.details.csharp.interfaceImplementation.declaration, schema: pt.elementType.schema, }; } else { // arg! it's not done yet. Hope it's not polymorphic itself. pt = { declaration: `${pt.elementType.schema.details.csharp.namespace}.${pt.elementType.schema.details.csharp.interfaceName}`, schema: pt.elementType.schema, }; } break; case codemodel_v3_1.JsonType.Array: pt = pt.elementType; break; default: pt = pt.elementType; break; } } const ptypes = new Array(); if (pt.schema && pt.schema && pt.schema.details.csharp.byReference) { ptypes.push(`typeof(${pt.schema.details.csharp.namespace}.${pt.schema.details.csharp.interfaceName}_Reference)`); // do we need polymorphic types for by-resource ? Don't think so. } else { ptypes.push(`typeof(${pt.declaration})`); if (pt.schema && pt.schema.details.csharp.classImplementation && pt.schema.details.csharp.classImplementation.discriminators) { ptypes.push(...[...pt.schema.details.csharp.classImplementation.discriminators.values()].map(each => `typeof(${each.modelInterface.fullName})`)); } } targetProperty.add(new codegen_csharp_1.Attribute(exports_1.ClientRuntime.InfoAttribute, { parameters: [ new codegen_csharp_1.LiteralExpression(`\nRequired = ${isRequired}`), new codegen_csharp_1.LiteralExpression(`\nReadOnly = ${isReadOnly}`), new codegen_csharp_1.LiteralExpression(`\nDescription = ${new codegen_csharp_1.StringExpression(description).value}`), new codegen_csharp_1.LiteralExpression(`\nSerializedName = ${new codegen_csharp_1.StringExpression(serializedName).value}`), new codegen_csharp_1.LiteralExpression(`\nPossibleTypes = new [] { ${ptypes.join(',').replace(/\?/g, '').replace(/undefined\./g, '')} }`), ] })); } exports.addInfoAttribute = addInfoAttribute; function NewAddInfoAttribute(targetProperty, pType, isRequired, isReadOnly, description, serializedName) { let pt = pType; while (pt.elementType) { switch (pt.elementType.schema.type) { case codemodel_v3_1.JsonType.Object: if (pt.elementType.schema.language.csharp.interfaceImplementation) { pt = { declaration: pt.elementType.schema.language.csharp.interfaceImplementation.declaration, schema: pt.elementType.schema, }; } else { // arg! it's not done yet. Hope it's not polymorphic itself. pt = { declaration: `${pt.elementType.schema.language.csharp.namespace}.${pt.elementType.schema.language.csharp.interfaceName}`, schema: pt.elementType.schema, }; } break; case codemodel_v3_1.JsonType.Array: pt = pt.elementType; break; default: pt = pt.elementType; break; } } const ptypes = new Array(); if (pt.schema && pt.schema && pt.schema.language.csharp.byReference) { ptypes.push(`typeof(${pt.schema.language.csharp.namespace}.${pt.schema.language.csharp.interfaceName}_Reference)`); // do we need polymorphic types for by-resource ? Don't think so. } else { ptypes.push(`typeof(${pt.declaration})`); if (pt.schema && pt.schema.language.csharp.classImplementation && pt.schema.language.csharp.classImplementation.discriminators) { ptypes.push(...[...pt.schema.language.csharp.classImplementation.discriminators.values()].map(each => `typeof(${each.modelInterface.fullName})`)); } } targetProperty.add(new codegen_csharp_1.Attribute(exports_1.ClientRuntime.InfoAttribute, { parameters: [ new codegen_csharp_1.LiteralExpression(`\nRequired = ${isRequired}`), new codegen_csharp_1.LiteralExpression(`\nReadOnly = ${isReadOnly}`), new codegen_csharp_1.LiteralExpression(`\nDescription = ${new codegen_csharp_1.StringExpression(description).value}`), new codegen_csharp_1.LiteralExpression(`\nSerializedName = ${new codegen_csharp_1.StringExpression(serializedName).value}`), new codegen_csharp_1.LiteralExpression(`\nPossibleTypes = new [] { ${ptypes.join(',').replace(/\?/g, '').replace(/undefined\./g, '')} }`), ] })); } exports.NewAddInfoAttribute = NewAddInfoAttribute; class CmdletClass extends codegen_csharp_1.Class { constructor(namespace, operation, state, objectInitializer) { var _a; // generate the 'variant' part of the name const noun = `${state.project.prefix}${operation.details.csharp.subjectPrefix}${operation.details.csharp.subject}`; const variantName = `${noun}${operation.details.csharp.name ? `_${operation.details.csharp.name}` : ''}`; const name = `${operation.details.csharp.verb}${variantName}`; super(namespace, name, powershell_declarations_1.PSCmdlet); this.dropBodyParameter = operation.details.csharp.dropBodyParameter ? true : false; this.apply(objectInitializer); this.operation = operation; this.apiCall = this.operation.callGraph[this.operation.callGraph.length - 1]; // create the response handlers this.responses = [...(0, linq_1.values)(this.apiCall.responses), ...(0, linq_1.values)(this.apiCall.exceptions)]; this.callbackMethods = (0, linq_1.values)(this.responses).toArray().map(each => { var _a; return new codegen_csharp_1.LiteralExpression(((_a = each.language.csharp) === null || _a === void 0 ? void 0 : _a.name) || ''); }); this.operationParameters = []; this.state = state; this.thingsToSerialize = []; this.variantName = variantName; this.hasStreamOutput = false; this.interfaces.push(exports_1.ClientRuntime.IEventListener); this.interfaces.push(exports_1.ClientRuntime.IContext); this.eventListener = new exports_1.EventListener(new codegen_csharp_1.LiteralExpression(`((${exports_1.ClientRuntime.IEventListener})this)`), true); this.isViaIdentity = variantName.indexOf('ViaIdentity') > 0; this.clientsidePagination = !!operation.details.csharp.clientsidePagination && !!((_a = this.apiCall.language.csharp) === null || _a === void 0 ? void 0 : _a.pageable); this.inputObjectParameterName = 'InputObject'; } async init() { // basic stuff this.addCommonStuff(); this.description = (0, codegen_1.escapeString)(this.operation.details.csharp.description); const $this = this; this.disableTransformIdentityType = await $this.state.getValue('disable-transform-identity-type', false); this.flattenUserAssignedIdentity = await $this.state.getValue('flatten-userassignedidentity', true); this.add(new codegen_csharp_1.Method('BeginProcessing', codegen_csharp_1.dotnet.Void, { override: codegen_csharp_1.Modifier.Override, access: codegen_csharp_1.Access.Protected, description: `(overrides the default BeginProcessing method in ${powershell_declarations_1.PSCmdlet})`, *body() { if ($this.state.project.azure) { yield `var telemetryId = ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.GetTelemetryId.Invoke();`; yield (0, codegen_csharp_1.If)('telemetryId != "" && telemetryId != "internal"', '__correlationId = telemetryId;'); } yield 'Module.Instance.SetProxyConfiguration(Proxy, ProxyCredential, ProxyUseDefaultCredentials);'; yield (0, codegen_csharp_1.If)($this.$('Break'), `${exports_1.ClientRuntime.AttachDebugger}.Break();`); yield $this.eventListener.syncSignal(powershell_declarations_1.Events.CmdletBeginProcessing); } })); // construct the class this.NewAddClassAttributes(this.operation, this.variantName); if (this.hasStreamOutput) { this.outFileParameter = this.add(new codegen_csharp_1.Property('OutFile', codegen_csharp_1.System.String, { attributes: [], description: 'Path to write output file to.' })); this.outFileParameter.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = true', 'HelpMessage = "Path to write output file to"'] })); this.outFileParameter.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ValidateNotNull)); this.outFileParameter.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Body`] })); } this.NewAddPowershellParameters(this.operation); // implement IEventListener this.implementIEventListener(); // implement part of the IContext this.implementIContext(); // add constructors this.implementConstructors(); // add callback methods this.NewImplementResponseMethod(); // processRecord this.NewImplementProcessRecord(); // find each parameter to the method, and find out where the value is going to come from. this.operationParameters = (0, linq_1.values)(this.apiCall.parameters). // filter out constants and path parameters when using piping for identity where(each => { var _a, _b; return !((_a = each.language.csharp) === null || _a === void 0 ? void 0 : _a.constantValue) && ((_b = each.language.default) === null || _b === void 0 ? void 0 : _b.name) !== '$host'; } /* && (!$this.isViaIdentity || each.in !== ParameterLocation.Path) */). select(p => { var _a, _b, _c; return { name: (_a = p.language.csharp) === null || _a === void 0 ? void 0 : _a.name, param: (0, linq_1.values)(this.properties). where(each => each.metadata.parameterDefinition). first(each => { var _a, _b; return ((_a = each.metadata.parameterDefinition.language.csharp) === null || _a === void 0 ? void 0 : _a.serializedName) === ((_b = p.language.csharp) === null || _b === void 0 ? void 0 : _b.serializedName); }), parameterLocation: (_c = (_b = p.protocol) === null || _b === void 0 ? void 0 : _b.http) === null || _c === void 0 ? void 0 : _c.in }; }). select(each => { if (each.param) { const httpParam = (each.param.metadata.parameterDefinition); if (httpParam.required) { return { name: each.param, expression: each.param, parameterLocation: each.parameterLocation }; } const httpParamTD = this.state.project.schemaDefinitionResolver.resolveTypeDeclaration(httpParam.schema, httpParam.required, this.state, this.state.project.fixedArray); return { name: each.param, expression: (0, codegen_csharp_1.toExpression)(`this.InvocationInformation.BoundParameters.ContainsKey("${each.param.value}") ? ${each.param.value} : ${httpParamTD.defaultOfType}`), parameterLocation: each.parameterLocation }; } return { name: each.name, expression: codegen_csharp_1.dotnet.Null, parameterLocation: each.parameterLocation }; }).toArray(); this.NewImplementProcessRecordAsync(); if (this.state.project.azure) { this.NewImplementWriteObject(); } this.debugMode = await this.state.getValue('debug', false); // json serialization this.NewImplementSerialization(this.operation); for (const prop of this.properties) { if (prop.name === 'Host') { prop['new'] = codegen_csharp_1.Modifier.New; } } return this; } get headerComment() { var _a, _b, _c, _d, _e; const header = super.headerComment; let ops = ''; for (const httpOperation of (0, linq_1.values)(this.operation.callGraph)) { const request = (_a = httpOperation.requests) === null || _a === void 0 ? void 0 : _a[0]; if (!request) { continue; } const httpMethod = (_c = (_b = request.protocol.http) === null || _b === void 0 ? void 0 : _b.method) !== null && _c !== void 0 ? _c : ''; const httpPath = (_e = (_d = request.protocol.http) === null || _d === void 0 ? void 0 : _d.path) !== null && _e !== void 0 ? _e : ''; ops = `${ops}\n[OpenAPI] ${httpOperation.language.default.name}=>${httpMethod.toUpperCase()}:"${httpPath}"`; if (this.debugMode) { // x-ms-metadata seems no longer exists // const m = (httpOperation.extensions && httpOperation.extensions['x-ms-metadata']) || (httpOperation.pathExtensions ? httpOperation.pathExtensions['x-ms-metadata'] : undefined); // if (m) { // ops = `${ops}\n [METADATA]\n${serialize(m)}`; // } ops = `${ops}\n [DETAILS]`; ops = `${ops}\n verb: ${this.operation.details.csharp.verb}`; ops = `${ops}\n subjectPrefix: ${this.operation.details.csharp.subjectPrefix}`; ops = `${ops}\n subject: ${this.operation.details.csharp.subject}`; ops = `${ops}\n variant: ${this.operation.details.csharp.name}`; } } return ops ? `${header}\n${(0, codegen_1.docComment)((0, codegen_csharp_1.xmlize)('remarks', ops))}` : header; } AddSwitchViewProperty(responseType = codegen_csharp_1.dotnet.Object) { const fieldNames = this.fields.map(f => f.name); if (!fieldNames.includes('_responseSize')) { this.add(new codegen_csharp_1.Field('_responseSize', codegen_csharp_1.dotnet.Int, { initialValue: '0', description: 'A flag to tell whether it is the first returned object in a call. Zero means no response yet. One means 1 returned object. Two means multiple returned objects in response.', access: codegen_csharp_1.Access.Private })); } if (!fieldNames.includes('_firstResponse')) { this.add(new codegen_csharp_1.Field('_firstResponse', responseType, { initialValue: codegen_csharp_1.dotnet.Null, description: 'A buffer to record first returned object in response.', access: codegen_csharp_1.Access.Private })); } } FlushResponse(singleFlush = true) { const fieldNames = this.fields.map(f => f.name); return fieldNames.includes('_responseSize') ? (0, codegen_csharp_1.If)('1 ==_responseSize', function* () { yield '// Flush buffer'; if (singleFlush) { yield 'WriteObject(_firstResponse);'; } else { yield 'WriteObject(_firstResponse.AddMultipleTypeNameIntoPSObject());'; } }) : ''; } WriteObjectWithViewControl(valueName, isEnumerable = false) { const $this = this; const lengthFunc = $this.state.project.fixedArray ? 'Length' : 'Count'; const listToArrayFunc = $this.state.project.fixedArray ? '.ToArray()' : ''; if ($this.state.project.autoSwitchView && !$this.operation.asjob) { if (isEnumerable) { return function* () { yield (0, codegen_csharp_1.If)(`null != ${valueName}`, function* () { yield (0, codegen_csharp_1.If)(`0 == _responseSize && 1 == ${valueName}.${lengthFunc}`, function* () { yield `_firstResponse = ${valueName}[0];`; yield '_responseSize = 1;'; }); yield (0, codegen_csharp_1.Else)(function* () { yield $this.FlushResponse(false); yield 'var values = new System.Collections.Generic.List<System.Management.Automation.PSObject>();'; yield (0, codegen_csharp_1.ForEach)('value', valueName, function* () { yield 'values.Add(value.AddMultipleTypeNameIntoPSObject());'; }); yield `WriteObject(values${listToArrayFunc}, true); `; yield '_responseSize = 2;'; }); }); }; } else { return function* () { yield (0, codegen_csharp_1.If)(`null != ${valueName}`, function* () { yield (0, codegen_csharp_1.If)('0 == _responseSize', function* () { yield `_firstResponse = ${valueName};`; yield '_responseSize = 1;'; }); yield (0, codegen_csharp_1.Else)(function* () { yield $this.FlushResponse(false); yield `WriteObject(${valueName}.AddMultipleTypeNameIntoPSObject());`; yield '_responseSize = 2;'; }); }); }; } } else { return `WriteObject(${valueName}, ${isEnumerable});`; } } addCommonStuff() { var _a, _b; // add a private copy of invocation information for our own uses. const privateInvocationInfo = this.add(new codegen_csharp_1.Field('__invocationInfo', powershell_declarations_1.InvocationInfo, { description: 'A copy of the Invocation Info (necessary to allow asJob to clone this cmdlet)', access: codegen_csharp_1.Access.Private })); this.invocationInfo = new codegen_csharp_1.Property('InvocationInformation', powershell_declarations_1.InvocationInfo, { description: 'Accessor for our copy of the InvocationInfo.' }); this.invocationInfo.get = (0, codegen_csharp_1.toExpression)(`${privateInvocationInfo.value} = ${privateInvocationInfo.value} ?? this.MyInvocation `); this.invocationInfo.set = new codegen_csharp_1.Statements(privateInvocationInfo.assign('value')); this.add(this.invocationInfo); if (this.state.project.azure) { this.correlationId = this.add(new codegen_csharp_1.Field('__correlationId', codegen_csharp_1.dotnet.String, { initialValue: 'System.Guid.NewGuid().ToString()', description: 'A unique id generatd for the this cmdlet when it is instantiated.', access: codegen_csharp_1.Access.Private })); this.processRecordId = this.add(new codegen_csharp_1.Field('__processRecordId', codegen_csharp_1.dotnet.String, { description: 'A unique id generatd for the this cmdlet when ProcessRecord() is called.', access: codegen_csharp_1.Access.Private })); } // switch view property if (this.state.project.autoSwitchView && !this.operation.asjob) { this.AddSwitchViewProperty(codegen_csharp_1.dotnet.Object); } // pipeline property this.add(new codegen_csharp_1.Property('Pipeline', exports_1.ClientRuntime.HttpPipeline, { getAccess: codegen_csharp_1.Access.Public, setAccess: codegen_csharp_1.Access.Public, description: `The instance of the <see cref="${exports_1.ClientRuntime.HttpPipeline}" /> that the remote call will use.` })); // client API property (gs01: fill this in correctly) const clientAPI = new codegen_csharp_1.ClassType((_a = this.state.model.language.csharp) === null || _a === void 0 ? void 0 : _a.namespace, ((_b = this.state.model.language.csharp) === null || _b === void 0 ? void 0 : _b.name) || ''); this.add(new codegen_csharp_1.LambdaProperty('Client', clientAPI, new codegen_csharp_1.LiteralExpression(`${this.state.project.serviceNamespace.moduleClass.declaration}.Instance.ClientAPI`), { description: 'The reference to the client API class.' })); this.add(new codegen_csharp_1.Method('StopProcessing', codegen_csharp_1.dotnet.Void, { access: codegen_csharp_1.Access.Protected, override: codegen_csharp_1.Modifier.Override, description: 'Interrupts currently running code within the command.' })).add(function* () { yield `((${exports_1.ClientRuntime.IEventListener})this).Cancel();`; yield 'base.StopProcessing();'; }); const $this = this; this.add(new codegen_csharp_1.Method('EndProcessing', codegen_csharp_1.dotnet.Void, { access: codegen_csharp_1.Access.Protected, override: codegen_csharp_1.Modifier.Override, description: 'Performs clean-up after the command execution' })).add(function* () { // gs01: remember what you were doing here to make it so these can be parallelized... if ($this.state.project.autoSwitchView && !$this.operation.asjob) { yield $this.FlushResponse(); } if (!$this.state.project.azure) { yield $this.eventListener.syncSignal(powershell_declarations_1.Events.CmdletEndProcessing); } else { yield `var telemetryInfo = ${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.GetTelemetryInfo?.Invoke(__correlationId);`; yield (0, codegen_csharp_1.If)('telemetryInfo != null', function* () { yield 'telemetryInfo.TryGetValue("ShowSecretsWarning", out var showSecretsWarning);'; yield 'telemetryInfo.TryGetValue("SanitizedProperties", out var sanitizedProperties);'; yield 'telemetryInfo.TryGetValue("InvocationName", out var invocationName);'; yield (0, codegen_csharp_1.If)('showSecretsWarning == "true"', function* () { yield (0, codegen_csharp_1.If)('string.IsNullOrEmpty(sanitizedProperties)', 'WriteWarning($"The output of cmdlet {invocationName} may compromise security by showing secrets. Learn more at https://go.microsoft.com/fwlink/?linkid=2258844");'); yield (0, codegen_csharp_1.Else)('WriteWarning($"The output of cmdlet {invocationName} may compromise security by showing the following secrets: {sanitizedProperties}. Learn more at https://go.microsoft.com/fwlink/?linkid=2258844");'); }); }); } }); // debugging const brk = this.add(new codegen_csharp_1.Property('Break', powershell_declarations_1.SwitchParameter, { attributes: [], description: 'Wait for .NET debugger to attach' })); brk.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'DontShow = true', 'HelpMessage = "Wait for .NET debugger to attach"'] })); brk.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); // Cmdlet Parameters for pipeline manipulations. const prepend = this.add(new codegen_csharp_1.Property('HttpPipelinePrepend', exports_1.ClientRuntime.SendAsyncSteps, { attributes: [], description: 'SendAsync Pipeline Steps to be prepended to the front of the pipeline' })); prepend.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'DontShow = true', 'HelpMessage = "SendAsync Pipeline Steps to be prepended to the front of the pipeline"'] })); prepend.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ValidateNotNull)); prepend.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); const append = this.add(new codegen_csharp_1.Property('HttpPipelineAppend', exports_1.ClientRuntime.SendAsyncSteps, { attributes: [], description: 'SendAsync Pipeline Steps to be appended to the front of the pipeline' })); append.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'DontShow = true', 'HelpMessage = "SendAsync Pipeline Steps to be appended to the front of the pipeline"'] })); append.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ValidateNotNull)); append.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); const proxyCredential = this.add(new codegen_csharp_1.Property('ProxyCredential', powershell_declarations_1.PSCredential, { attributes: [], description: 'Credentials for a proxy server to use for the remote call' })); proxyCredential.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'DontShow = true', 'HelpMessage = "Credentials for a proxy server to use for the remote call"'] })); proxyCredential.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ValidateNotNull)); proxyCredential.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); const useDefaultCreds = this.add(new codegen_csharp_1.Property('ProxyUseDefaultCredentials ', powershell_declarations_1.SwitchParameter, { attributes: [], description: 'Use the default credentials for the proxy' })); useDefaultCreds.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'DontShow = true', 'HelpMessage = "Use the default credentials for the proxy"'] })); useDefaultCreds.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); const proxyUri = this.add(new codegen_csharp_1.Property('Proxy', codegen_csharp_1.System.Uri, { attributes: [], description: 'The URI for the proxy server to use' })); proxyUri.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'DontShow = true', 'HelpMessage = "The URI for the proxy server to use"'] })); proxyUri.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); if (this.state.project.azure) { this.defaultProfile = this.add(new codegen_csharp_1.Property('DefaultProfile', powershell_declarations_1.PSObject, { description: 'The DefaultProfile parameter is not functional. Use the SubscriptionId parameter when available if executing the cmdlet against a different subscription' })); this.defaultProfile.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'HelpMessage = "The DefaultProfile parameter is not functional. Use the SubscriptionId parameter when available if executing the cmdlet against a different subscription."'] })); this.defaultProfile.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ValidateNotNull)); this.defaultProfile.add(new codegen_csharp_1.Attribute(powershell_declarations_1.Alias, { parameters: ['"AzureRMContext"', '"AzureCredential"'] })); this.defaultProfile.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Azure`] })); } } NewImplementProcessRecord() { const $this = this; const operation = $this.operation; this.add(new codegen_csharp_1.Method('ProcessRecord', undefined, { access: codegen_csharp_1.Access.Protected, override: codegen_csharp_1.Modifier.Override, description: 'Performs execution of the command.' })).add(function* () { yield $this.eventListener.syncSignal(powershell_declarations_1.Events.CmdletProcessRecordStart); if ($this.state.project.azure) { yield $this.processRecordId.assign('System.Guid.NewGuid().ToString()'); } yield (0, codegen_csharp_1.Try)(function* () { var _a; yield '// work'; const normal = new codegen_csharp_1.Statements(function* () { const acr = new codegen_csharp_1.LocalVariable('asyncCommandRuntime', codegen_csharp_1.dotnet.Var, { initializer: powershell_declarations_1.AsyncCommandRuntime.new(codegen_csharp_1.dotnet.This, $this.cancellationToken) }); yield (0, codegen_csharp_1.Using)(acr.declarationExpression, function* () { yield `${acr}.Wait( ProcessRecordAsync(),${$this.cancellationToken});`; }); }); if (operation.asjob) { const asjob = $this.add(new codegen_csharp_1.Property('AsJob', powershell_declarations_1.SwitchParameter, { description: 'when specified, runs this cmdlet as a PowerShell job' })); asjob.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'HelpMessage = "Run the command as a job"'] })); asjob.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); const nowait = $this.add(new codegen_csharp_1.Property('NoWait', powershell_declarations_1.SwitchParameter, { description: 'when specified, will make the remote call, and return an AsyncOperationResponse, letting the remote operation continue asynchronously.' })); nowait.add(new codegen_csharp_1.Attribute(powershell_declarations_1.ParameterAttribute, { parameters: ['Mandatory = false', 'HelpMessage = "Run the command asynchronously"'] })); nowait.add(new codegen_csharp_1.Attribute(powershell_declarations_1.CategoryAttribute, { parameters: [`${powershell_declarations_1.ParameterCategory}.Runtime`] })); } const work = operation.asjob ? function* () { yield (0, codegen_csharp_1.If)('true == MyInvocation?.BoundParameters?.ContainsKey("AsJob")', function* () { // clone the cmdlet instance, since the instance can be reused and overwrite data. const instance = new codegen_csharp_1.LocalVariable('instance', codegen_csharp_1.dotnet.Var, { initializer: 'this.Clone()' }); yield instance.declarationStatement; // create the job (which will set the CommandRuntime of the clone to the AsyncJob itself) const job = new codegen_csharp_1.LocalVariable('job', codegen_csharp_1.dotnet.Var, { initializer: powershell_declarations_1.AsyncJob.new(instance, 'this.MyInvocation.Line, this.MyInvocation.MyCommand.Name, this._cancellationTokenSource.Token', 'this._cancellationTokenSource.Cancel') }); yield job.declarationStatement; // add the job to the repository yield `JobRepository.Add(${job});`; // invoke the cmdlet's PRA const task = new codegen_csharp_1.LocalVariable('task', codegen_csharp_1.dotnet.Var, { initializer: `${instance}.ProcessRecordAsync()` }); yield task.declarationStatement; // have the AsyncJob monitor the lifetime of the Task yield `${job}.Monitor(${task});`; // return the job to the user now. yield `WriteObject(${job});`; }); yield (0, codegen_csharp_1.Else)(normal); } : normal; if ((0, command_operation_1.isWritableCmdlet)(operation) && !operation.details.csharp.supportShouldProcess) { yield (0, codegen_csharp_1.If)(`ShouldProcess($"Call remote '${(_a = $this.apiCall.language.csharp) === null || _a === void 0 ? void 0 : _a.name}' operation")`, work); } else { yield work; } }); const aggregateException = new codegen_csharp_1.Parameter('aggregateException', codegen_csharp_1.System.AggregateException); yield (0, codegen_csharp_1.Catch)(aggregateException, function* () { yield '// unroll the inner exceptions to get the root cause'; yield (0, codegen_csharp_1.ForEach)('innerException', new codegen_csharp_1.LiteralExpression(`${aggregateException.use}.Flatten().InnerExceptions`), function* () { yield $this.eventListener.syncSignal(powershell_declarations_1.Events.CmdletException, new codegen_csharp_1.LiteralExpression('$"{innerException.GetType().Name} - {innerException.Message} : {innerException.StackTrace}"')); yield '// Write exception out to error channel.'; yield `WriteError( new ${powershell_declarations_1.ErrorRecord}(innerException,string.Empty, ${(0, powershell_declarations_1.ErrorCategory)('NotSpecified')}, null) );`; }); }); const exception = new codegen_csharp_1.Parameter('exception', codegen_csharp_1.System.Exception); yield (0, codegen_csharp_1.Catch)(exception, function* () { yield $this.eventListener.syncSignal(powershell_declarations_1.Events.CmdletException, new codegen_csharp_1.LiteralExpression(`$"{${exception.use}.GetType().Name} - {${exception.use}.Message} : {${exception.use}.StackTrace}"`)); yield '// Write exception out to error channel.'; yield `WriteError( new ${powershell_declarations_1.ErrorRecord}(${exception.use},string.Empty, ${(0, powershell_declarations_1.ErrorCategory)('NotSpecified')}, null) );`; }, { when: new codegen_csharp_1.LiteralExpression('(exception as System.Management.Automation.PipelineStoppedException)== null || (exception as System.Management.Automation.PipelineStoppedException).InnerException != null') }); yield (0, codegen_csharp_1.Finally)(function* () { yield $this.eventListener.syncSignalNoCheck(powershell_declarations_1.Events.CmdletProcessRecordEnd); }); }); } NewImplementProcessRecordAsync() { const $this = this; const operationParameters = $this.operationParameters; const pipeline = $this.$('Pipeline'); this.serializationMode = this.bodyParameter ? (this.operation.operationType === command_operation_1.OperationType.Create ? exports_1.ClientRuntime.SerializationMode.IncludeCreate : (this.operation.operationType === command_operation_1.OperationType.Update ? exports_1.ClientRuntime.SerializationMode.IncludeUpdate : undefined)) : undefined; if (this.operation.commandType === command_operation_1.CommandType.GetPut || this.operation.commandType === command_operation_1.CommandType.ManagedIdentityUpdate) { this.serializationMode = exports_1.ClientRuntime.SerializationMode.IncludeCreateOrUpdate; } const PRA = this.add(new codegen_csharp_1.Method('ProcessRecordAsync', codegen_csharp_1.System.Threading.Tasks.Task(), { access: codegen_csharp_1.Access.Protected, async: codegen_csharp_1.Modifier.Async, description: 'Performs execution of the command, working asynchronously if required.', returnsDescription: `A <see cref="${codegen_csharp_1.System.Threading.Tasks.Task()}" /> that will be complete when handling of the method is completed.` })); // we don't want to use SynchContext here. PRA.push((0, codegen_csharp_1.Using)('NoSynchronizationContext', '')); PRA.add(function* () { if ($this.apProp && $this.bodyParameter && $this.bodyParameterInfo) { // yield `${ClientRuntime}.DictionaryExtensions.HashTableToDictionary<${$this.bodyParameterInfo.type.declaration},${$this.bodyParameterInfo.valueType.declaration}>(${$this.apProp.value},${$this.bodyParameter.Cast($this.bodyParameterInfo.type)});`; let vt = $this.bodyParameterInfo.valueType.declaration; if (vt.endsWith('SwitchParameter')) { vt = 'bool'; } yield `${exports_1.ClientRuntime}.DictionaryExtensions.HashTableToDictionary<${vt}>(${$this.apProp.value},${$this.bodyParameter}.AdditionalProperties);`; } // construct the call to the operation if (!$this.state.project.azure) { yield $this.eventListener.signal(powershell_declarations_1.Events.CmdletProcessRecordAsyncStart); } yield $this.eventListener.signal(powershell_declarations_1.Events.CmdletGetPipeline); if ($this.state.project.azure) { yield pipeline.assign(new codegen_csharp_1.LiteralExpression(`${$this.state.project.serviceNamespace.moduleClass.declaration}.Instance.Crea