@autorest/powershell
Version:
AutoRest PowerShell Cmdlet Generator
215 lines • 7.89 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.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