UNPKG

@autorest/powershell

Version:
215 lines 7.89 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.ModelState = void 0; const extension_base_1 = require("@autorest/extension-base"); const codegen_1 = require("@azure-tools/codegen"); const tsp_host_1 = require("./tsp-host"); const path_1 = require("path"); class ModelState extends codegen_1.Initializer { constructor(service, objectInitializer) { super(); this.service = service; this.currentPath = new Array(); this._debug = false; this._verbose = false; this.errorCount = 0; this.apply(objectInitializer); } async init(project) { if (this.service instanceof tsp_host_1.TspHostImpl) { // skip init for tsp this.outputFolder = await this.getValue('output-folder', './generated'); this.initContext(project); return this; } const m = await ModelState.getModel(this.service); this.model = m.model; this.documentName = m.filename; this.initContext(project); this._debug = await this.getValue('debug', false); this._verbose = await this.getValue('verbose', false); return this; } async initContext(project) { this.context = this.context || { $config: await this.service.getValue(''), $project: project, $lib: { path: require('path') } }; return this; } async readFile(filename) { return this.service.readFile(filename); } async getValue(key, defaultValue) { // check if it's in the model first let value = this.model && this.model.language && this.model.language.default ? this.model.language.default[key] : undefined; // fall back to the configuration if (value == null || value === undefined) { value = await this.service.getValue(key); } // try as a safe eval execution. if (value === null || value === undefined) { try { value = (0, codegen_1.safeEval)(key, this.context); } catch (_a) { value = null; } } if (defaultValue === undefined && value === null) { throw new Error(`No value for configuration key '${key}' was provided`); } if (typeof value === 'string') { value = await this.resolveVariables(value); } // ensure that any content variables are resolved at the end. return (value !== null ? value : defaultValue); } async setValue(key, value) { this.model.language.default[key] = value; } async listInputs(artifactType) { return this.service.listInputs(artifactType); } async protectFiles(path) { return this.service.protectFiles(path); } writeFile(filename, content, sourceMap, artifactType) { return this.service.writeFile({ filename: this.outputFolder ? (0, path_1.join)(this.outputFolder, filename) : filename, content: content, sourceMap: sourceMap, artifactType: artifactType }); } message(message) { if (message.Channel === extension_base_1.Channel.Debug && this._debug === false) { return; } if (message.Channel === extension_base_1.Channel.Verbose && this._verbose === false) { return; } return this.service.message(message); } updateConfigurationFile(filename, content) { return this.service.UpdateConfigurationFile(filename, content); } async getConfigurationFile(filename) { return this.service.GetConfigurationFile(filename); } static async getModel(service) { const files = await service.listInputs(); const filename = files[0]; if (files.length === 0) { throw new Error('Inputs missing.'); } return { filename, model: (0, codegen_1.deserialize)(await service.readFile(filename), filename) }; } replacer(key, value) { this.cache = this.cache || new Array(); if (typeof value === 'object' && value !== null) { if (this.cache.indexOf(value) !== -1) { // Duplicate reference found try { // If this value does not reference a parent it can be deduped return JSON.parse(JSON.stringify(value)); } catch (error) { // discard key if value cannot be deduped return; } } // Store value in our collection this.cache.push(value); } return value; } async resolveVariables(input) { let output = input; for (const rx of [/\$\((.*?)\)/g, /\$\{(.*?)\}/g]) { /* eslint-disable */ for (let match; match = rx.exec(input);) { const text = match[0]; const inner = match[1]; let value = await this.getValue(inner, null); if (value !== undefined && value !== null) { if (typeof value === 'object') { value = JSON.stringify(value, this.replacer, 2); } if (value === '{}') { value = 'true'; } output = output.replace(text, value); } } } return output; } path(...childPath) { // this strategy for tracking source path locations // has proved fundementally crappy. // will be removing this stuff and transitioning to source-track method. //const result = new ModelState<T>(this.service, <any>this); //result.currentPath = [...this.currentPath, ...childPath]; // return result; return this; } checkpoint() { if (this.errorCount > 0) { throw new Error(); } } msg(channel, message, key, details) { this.message({ Channel: channel, Key: key, Source: [ { document: this.documentName, Position: { path: this.currentPath } } ], Text: message, Details: details }); } warning(message, key, details) { this.msg(extension_base_1.Channel.Warning, message, key, details); } hint(message, key, details) { this.msg(extension_base_1.Channel.Hint, message, key, details); } error(message, key, details) { this.errorCount++; this.msg(extension_base_1.Channel.Error, message, key, details); } fatal(message, key, details) { this.errorCount++; this.msg(extension_base_1.Channel.Fatal, message, key, details); } output(channel, message, details) { this.message({ Channel: channel, Text: message, Details: details }); } debug(message, details) { this.output(extension_base_1.Channel.Debug, message, details); } verbose(message, details) { this.output(extension_base_1.Channel.Verbose, message, details); } log(message, details) { this.output(extension_base_1.Channel.Information, message, details); } } exports.ModelState = ModelState; //# sourceMappingURL=model-state.js.map