@autorest/powershell
Version:
AutoRest PowerShell Cmdlet Generator
721 lines • 171 kB
JavaScript
"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