UNPKG

@autorest/powershell

Version:
180 lines 11.3 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.tweakModelAzurePluginV2 = exports.tweakModel = void 0; const linq_1 = require("@azure-tools/linq"); const model_state_1 = require("../utils/model-state"); const codemodel_1 = require("@autorest/codemodel"); const codegen_1 = require("@azure-tools/codegen"); const xmsPageable = 'x-ms-pageable'; async function tweakModel(state) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; const model = state.model; // service.message{ Channel: Channel.Debug, Text: "THIS IS THE AZURE TWEAKER" }); // TODO: // look at models, and extract out any case that has an IRESOURCE, IPROXYRESOURCE, etc. // and use the common versions of those models. // Is the result marked x-ms-pagable? // identify the next link (null means just get the results as an array) // if nextLinkName is null, then it won't actually page, but we'd like to unroll the contents anyway. for (const group of (0, linq_1.values)(model.operationGroups)) { for (const operation of (0, linq_1.values)(group.operations)) { if (operation.extensions && operation.extensions[xmsPageable]) { // it's marked pagable. operation.language.default.pageable = { responseType: 'pageable', nextLinkName: operation.extensions[xmsPageable].nextLinkName || undefined, itemName: operation.extensions[xmsPageable].itemName || 'value', operationName: operation.extensions[xmsPageable].operationName || `${operation.language.default.name}Next`, }; continue; } // let's just check to see if it looks like it's supposed to be a collection for (const response of (0, linq_1.values)(operation.responses)) { // does the response have a schema? // TODO: check schema if (getSchema(response)) { const schema = getSchema(response); // is this just an array response? if (schema.type === codemodel_1.SchemaType.Array) { operation.language.default.pageable = { responseType: 'array', }; continue; } // if it returns an object, let's see what's inside... if (schema.type === codemodel_1.SchemaType.Object) { const objSchema = schema; // does it have a single member that is an array (ie, value : [...]) if ((0, linq_1.length)(objSchema.properties) === 1 && !objSchema.parents) { const property = (_a = objSchema.properties) === null || _a === void 0 ? void 0 : _a[0]; if (property) { if (property.schema.type === codemodel_1.SchemaType.Array) { // nested array! operation.language.default.pageable = { responseType: 'nested-array', itemName: property.serializedName, }; } continue; } } // xichen: If response schema has only 2 properties and one of it is nextLink, the other is array // does it kinda look like a x-ms-pagable (value/nextlink?) if ((0, linq_1.length)(objSchema.properties) === 2 && !objSchema.parents) { const hasNextLink = (_b = objSchema.properties) === null || _b === void 0 ? void 0 : _b.some((prop) => prop.serializedName === 'nextLink'); if (hasNextLink) { const property = (_c = objSchema.properties) === null || _c === void 0 ? void 0 : _c.find((prop) => prop.serializedName !== 'nextLink'); if (property) { if (property.schema.type === codemodel_1.SchemaType.Array) { // nested array! operation.language.default.pageable = { responseType: 'nested-array', itemName: property.serializedName, nextLinkName: 'nextLink' }; } continue; } } } } } } } } // make sure that all operations with lro have an options block. for (const group of (0, linq_1.values)(model.operationGroups)) { for (const operation of (0, linq_1.values)(group.operations)) { if (operation.extensions && operation.extensions['x-ms-long-running-operation']) { operation.language.default.asjob = true; operation.language.default.lro = operation.extensions['x-ms-long-running-operation-options'] || { 'final-state-via': 'default' }; // LRO 201 and 202 responses are handled internally, so remove any 201/202 responses in the operation operation.responses = (operation.responses).filter(each => { var _a, _b; return ((_a = each.protocol.http) === null || _a === void 0 ? void 0 : _a.statusCodes[0]) !== '201' && ((_b = each.protocol.http) === null || _b === void 0 ? void 0 : _b.statusCodes[0]) !== '202'; }); //delete operation.responses['201']; //delete operation.responses['202']; // for lro deletion, we need to add the 200 response if it's not already there. if (operation.requests && (((_d = operation.requests[0].protocol.http) === null || _d === void 0 ? void 0 : _d.method) === 'delete' || ((_e = operation.requests[0].protocol.http) === null || _e === void 0 ? void 0 : _e.method) === 'post')) { if (!operation.responses.find(each => { var _a; return ((_a = each.protocol.http) === null || _a === void 0 ? void 0 : _a.statusCodes[0]) === '200'; })) { const response = new codemodel_1.Response(); response.protocol.http = (_f = response.protocol.http) !== null && _f !== void 0 ? _f : new codemodel_1.Protocol(); response.protocol.http.statusCodes = ['200']; operation.responses.push(response); } } } } } // xichen: Cannot find 'x-ms-metadata' from swagger repo. Are we still using it? // Api Version parameter handling for Azure. // if there is only a single api-version for the operation, let's just make it a constant // otherwise, we need to make it selectable, but default to the 'latest' version there is. for (const group of (0, linq_1.values)(model.operationGroups)) { for (const operation of (0, linq_1.values)(group.operations)) { const apiVersions = operation.apiVersions; for (const parameter of (0, linq_1.values)(operation.parameters)) { if (parameter.language.default.serializedName === 'api-version') { // only set it if it hasn't been set yet. // if (parameter.details.default.constantValue) { //continue; //} if (apiVersions) { // set the constant value to the first one if ((0, linq_1.length)(apiVersions) === 1) { parameter.language.default.constantValue = apiVersions[0].version; continue; } // otherwise, the parameter can't have a constant value parameter.language.default.constantValue = undefined; // mark it so that we can add profile support in the method generation parameter.language.default.apiversion = true; } } } } } // when make-sub-resources-byreference is specified, mark models with a writable id as byref. if (await state.getValue('azure', false) && await state.getValue('make-sub-resources-byreference', false)) { for (const schema of (0, linq_1.values)((_g = model.schemas.objects) !== null && _g !== void 0 ? _g : [])) { // find schemas that have an 'id' and are not readonly if ((0, linq_1.values)((0, codemodel_1.getAllProperties)(schema)).any(prop => prop.serializedName === 'id' && !prop.language.default.readOnly)) { // look thru the operations, and the PUT methods for (const group of model.operationGroups) { for (const op of (0, linq_1.values)(group.operations)) { for (const request of (_h = op.requests) !== null && _h !== void 0 ? _h : []) { if (((_j = request.protocol.http) === null || _j === void 0 ? void 0 : _j.method) === 'put') { for (const response of (_k = op.responses) !== null && _k !== void 0 ? _k : []) { // see if any of the responses have the same schema as we are looking for if (getSchema(response) === schema) { // tell it not to inline that schema.language.default.byReference = true; break; } } break; } } } } } } } return model; } exports.tweakModel = tweakModel; function getSchema(response) { return response.schema; } // Azure version - // Additional tweaks the code model to adjust things so that the code will generate better. async function tweakModelAzurePluginV2(service) { const state = await new model_state_1.ModelState(service).init(); await service.writeFile({ filename: 'code-model-v4-tweakcodemodelazure-v2.yaml', content: (0, codegen_1.serialize)(await tweakModel(state)), sourceMap: undefined, artifactType: 'code-model-v4' }); } exports.tweakModelAzurePluginV2 = tweakModelAzurePluginV2; //# sourceMappingURL=plugin-tweak-model-azure-v2.js.map