@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
187 lines (185 loc) • 8.57 kB
JavaScript
/* eslint-disable no-console */
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const path_1 = tslib_1.__importDefault(require("path"));
const plugin_error_1 = tslib_1.__importDefault(require("plugin-error"));
const through2_1 = tslib_1.__importDefault(require("through2"));
const vinyl_1 = tslib_1.__importDefault(require("vinyl"));
const util = tslib_1.__importStar(require("../utilities"));
const PsCode = tslib_1.__importStar(require("./ps-code-convert"));
const ps_code_convert_1 = require("./ps-code-convert");
const PLUGIN_NAME = 'gulp-ps-code';
/**
* Plugin level function
*/
function gulpPsCode(options) {
//
// (Options):
//
// name of PowerShell module. (required)
// powerShellModuleName: string
//
// name of generated file.
// name: string; default is 'powershell-script.ts'
//
// base path of powershell files.
// basePath: string; default is 'src/resources/scripts'
//
// generated path of powershell files.
// generatedPath: string; default is 'src/generated/scripts'
//
// remove comments at default.
// noComments: boolean;
//
// validate content of PowerShell script.
// - non-ascii code, no comments, unsupported script file name and unofficial verb
// validate: boolean;
//
// JEA data object format.
// jea: boolean
//
// name of resource root. the key name of resjson.
// resourceName: string
//
// override options settings if not specified.
options = Object.assign({
name: 'powershell-scripts.ts',
basePath: 'src\\resources\\scripts',
generatedPath: 'src\\generated\\scripts',
noComments: true,
validate: true,
jea: true
}, options || {});
const groups = {};
const collection = {};
let lastFile = null;
return through2_1.default.obj(function (file, enc, cb) {
let error = null;
try {
if (!options.powerShellModuleName) {
throw new Error('gulp-ps-code requires powerShellModuleName option.');
}
const path = path_1.default.parse(file.path);
if (path.ext === '.ps1') {
let relPath = file.path.substring(file.cwd.length + 1);
relPath = relPath.substring(0, relPath.length - path.base.length - 1);
let groupName = ps_code_convert_1.PsCodeConverter.defaultGroup;
if (relPath === options.generatedPath) {
groupName = ps_code_convert_1.PsCodeConverter.generatedGroup;
}
else {
if (relPath !== options.basePath && relPath.indexOf(options.basePath) === 0) {
groupName = relPath.substring(options.basePath.length + 1);
}
}
let group = groups[groupName];
if (!group) {
group = {};
groups[groupName] = group;
}
if (collection[path.base]) {
throw new Error('gulp-ps-code requires unique name of ps file, conflicted with ' + path.base);
}
collection[path.base] = true;
const data = file.contents.toString('utf8');
if (options.validate) {
// validate non-ascii code presence.
const lines = data.split('\n');
let errorCode = false;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
for (let j = 0; j < line.length; j++) {
const code = line.charCodeAt(j);
if (code > 0x7f) {
let point = '';
if (j > 0) {
for (let k = 1; k <= j; k++) {
point += ' ';
}
}
console.error(`File: ${path.base}, Line: ${i + 1}, Position: ${j + 1}, Char: '${line.charAt(j)}', Code: ${code}`);
console.error(line);
console.error(point + '^----<see>');
errorCode = true;
}
}
}
if (errorCode) {
throw new Error('File contained non ascii code: ' + path.base);
}
// validate script file name.
const segments = path.base.split('-');
if (segments.length !== 2) {
console.error('File doesn\'t follow <Verb>-<Name>.ps1 format to support JEA: ' + path.base);
}
else {
// validate script verb.
const found = ps_code_convert_1.PsCodeConverter.verbs.find(x => x === segments[0]);
if (!found) {
console.error('File doesn\'t follow official verb name to support JEA: ' + path.base);
console.error('Try Get-Verb PowerShell command to find official verbs.');
console.error('https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx');
errorCode = true;
}
else {
// validate comments for JEA.
const commentIndex = data.indexOf('{');
const comments = commentIndex < 0 ? data : data.substring(0, commentIndex);
const commentsMinimum = comments.indexOf('<#') >= 0
&& comments.indexOf('#>') > 0
&& comments.indexOf('.SYNOPSIS') > 0
&& comments.indexOf('.DESCRIPTION') > 0
&& comments.indexOf('.ROLE') > 0;
if (!commentsMinimum) {
console.error('The script file doesn\'t contain formal PowerShell comment section to support JEA: ' + path.base);
console.error('Requires .SYNOPSIS, .DESCRIPTION and .ROLE comments.');
errorCode = true;
}
let roleLine = false;
for (const comment of comments.split('\n')) {
if (roleLine) {
const role = comment.trim();
if (role === '' || role === '#>') {
break;
}
if (role !== 'Administrators' && role !== 'Readers' && role !== 'Hyper-V-Administrators') {
console.error('The script file contains unsupported JEA ROLE "' + role + '": ' + path.base);
errorCode = true;
}
}
if (comment.indexOf('.ROLE') >= 0) {
roleLine = true;
}
}
}
}
if (errorCode) {
throw new Error('File cannot support JEA: ' + path.base);
}
}
group[path.base] = data;
lastFile = file;
}
}
catch (e) {
error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ?
util.extendError(new plugin_error_1.default({ plugin: PLUGIN_NAME, message: e.message }), e) : e;
}
return cb(error);
}, function (cb) {
const converter = new PsCode.PsCodeConverter(options);
converter.contentReset();
converter.generate(groups);
const tsFile = new vinyl_1.default({
cwd: lastFile.cwd,
base: lastFile.base,
path: lastFile.base + '/' + options.name,
contents: Buffer.from(converter.content, 'utf8')
});
this.push(tsFile);
cb();
});
}
module.exports = gulpPsCode;
//# sourceMappingURL=index.js.map