Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/build/lib
diff options
context:
space:
mode:
Diffstat (limited to 'build/lib')
-rw-r--r--build/lib/policies.js476
-rw-r--r--build/lib/policies.ts674
-rw-r--r--build/lib/tsb/builder.js2
-rw-r--r--build/lib/tsb/builder.ts2
-rw-r--r--build/lib/watch/.gitignore1
-rw-r--r--build/lib/watch/package.json12
-rw-r--r--build/lib/watch/yarn.lock400
7 files changed, 1152 insertions, 415 deletions
diff --git a/build/lib/policies.js b/build/lib/policies.js
new file mode 100644
index 00000000000..3e2a10df350
--- /dev/null
+++ b/build/lib/policies.js
@@ -0,0 +1,476 @@
+"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 });
+const child_process_1 = require("child_process");
+const fs_1 = require("fs");
+const path = require("path");
+const byline = require("byline");
+const ripgrep_1 = require("@vscode/ripgrep");
+const Parser = require("tree-sitter");
+const node_fetch_1 = require("node-fetch");
+const { typescript } = require('tree-sitter-typescript');
+const product = require('../../product.json');
+function isNlsString(value) {
+ return value ? typeof value !== 'string' : false;
+}
+function isStringArray(value) {
+ return !value.some(s => isNlsString(s));
+}
+function isNlsStringArray(value) {
+ return value.every(s => isNlsString(s));
+}
+var PolicyType;
+(function (PolicyType) {
+ PolicyType[PolicyType["StringEnum"] = 0] = "StringEnum";
+})(PolicyType || (PolicyType = {}));
+function renderADMLString(prefix, moduleName, nlsString, translations) {
+ let value;
+ if (translations) {
+ const moduleTranslations = translations[moduleName];
+ if (moduleTranslations) {
+ value = moduleTranslations[nlsString.nlsKey];
+ }
+ }
+ if (!value) {
+ value = nlsString.value;
+ }
+ return `<string id="${prefix}_${nlsString.nlsKey}">${value}</string>`;
+}
+class BasePolicy {
+ constructor(policyType, name, category, minimumVersion, description, moduleName) {
+ this.policyType = policyType;
+ this.name = name;
+ this.category = category;
+ this.minimumVersion = minimumVersion;
+ this.description = description;
+ this.moduleName = moduleName;
+ }
+ renderADMLString(nlsString, translations) {
+ return renderADMLString(this.name, this.moduleName, nlsString, translations);
+ }
+ renderADMX(regKey) {
+ return [
+ `<policy name="${this.name}" class="Both" displayName="$(string.${this.name})" explainText="$(string.${this.name}_${this.description.nlsKey})" key="Software\\Policies\\Microsoft\\${regKey}" presentation="$(presentation.${this.name})">`,
+ ` <parentCategory ref="${this.category.name.nlsKey}" />`,
+ ` <supportedOn ref="Supported_${this.minimumVersion.replace(/\./g, '_')}" />`,
+ ` <elements>`,
+ ...this.renderADMXElements(),
+ ` </elements>`,
+ `</policy>`
+ ];
+ }
+ renderADMLStrings(translations) {
+ return [
+ `<string id="${this.name}">${this.name}</string>`,
+ this.renderADMLString(this.description, translations)
+ ];
+ }
+ renderADMLPresentation() {
+ return `<presentation id="${this.name}">${this.renderADMLPresentationContents()}</presentation>`;
+ }
+}
+class BooleanPolicy extends BasePolicy {
+ static from(name, category, minimumVersion, description, moduleName, settingNode) {
+ const type = getStringProperty(settingNode, 'type');
+ if (type !== 'boolean') {
+ return undefined;
+ }
+ return new BooleanPolicy(name, category, minimumVersion, description, moduleName);
+ }
+ constructor(name, category, minimumVersion, description, moduleName) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ }
+ renderADMXElements() {
+ return [
+ `<boolean id="${this.name}" valueName="${this.name}">`,
+ ` <trueValue><decimal value="1" /></trueValue><falseValue><decimal value="0" /></falseValue>`,
+ `</boolean>`
+ ];
+ }
+ renderADMLPresentationContents() {
+ return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
+ }
+}
+class IntPolicy extends BasePolicy {
+ constructor(name, category, minimumVersion, description, moduleName, defaultValue) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ this.defaultValue = defaultValue;
+ }
+ static from(name, category, minimumVersion, description, moduleName, settingNode) {
+ const type = getStringProperty(settingNode, 'type');
+ if (type !== 'number') {
+ return undefined;
+ }
+ const defaultValue = getIntProperty(settingNode, 'default');
+ if (typeof defaultValue === 'undefined') {
+ throw new Error(`Missing required 'default' property.`);
+ }
+ return new IntPolicy(name, category, minimumVersion, description, moduleName, defaultValue);
+ }
+ renderADMXElements() {
+ return [
+ `<decimal id="${this.name}" valueName="${this.name}" />`
+ // `<decimal id="Quarantine_PurgeItemsAfterDelay" valueName="PurgeItemsAfterDelay" minValue="0" maxValue="10000000" />`
+ ];
+ }
+ renderADMLPresentationContents() {
+ return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
+ }
+}
+class StringPolicy extends BasePolicy {
+ static from(name, category, minimumVersion, description, moduleName, settingNode) {
+ const type = getStringProperty(settingNode, 'type');
+ if (type !== 'string') {
+ return undefined;
+ }
+ return new StringPolicy(name, category, minimumVersion, description, moduleName);
+ }
+ constructor(name, category, minimumVersion, description, moduleName) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ }
+ renderADMXElements() {
+ return [`<text id="${this.name}" valueName="${this.name}" required="true" />`];
+ }
+ renderADMLPresentationContents() {
+ return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
+ }
+}
+class StringEnumPolicy extends BasePolicy {
+ constructor(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ this.enum_ = enum_;
+ this.enumDescriptions = enumDescriptions;
+ }
+ static from(name, category, minimumVersion, description, moduleName, settingNode) {
+ const type = getStringProperty(settingNode, 'type');
+ if (type !== 'string') {
+ return undefined;
+ }
+ const enum_ = getStringArrayProperty(settingNode, 'enum');
+ if (!enum_) {
+ return undefined;
+ }
+ if (!isStringArray(enum_)) {
+ throw new Error(`Property 'enum' should not be localized.`);
+ }
+ const enumDescriptions = getStringArrayProperty(settingNode, 'enumDescriptions');
+ if (!enumDescriptions) {
+ throw new Error(`Missing required 'enumDescriptions' property.`);
+ }
+ else if (!isNlsStringArray(enumDescriptions)) {
+ throw new Error(`Property 'enumDescriptions' should be localized.`);
+ }
+ return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions);
+ }
+ renderADMXElements() {
+ return [
+ `<enum id="${this.name}" valueName="${this.name}">`,
+ ...this.enum_.map((value, index) => ` <item displayName="$(string.${this.name}_${this.enumDescriptions[index].nlsKey})"><value><string>${value}</string></value></item>`),
+ `</enum>`
+ ];
+ }
+ renderADMLStrings(translations) {
+ return [
+ ...super.renderADMLStrings(translations),
+ ...this.enumDescriptions.map(e => this.renderADMLString(e, translations))
+ ];
+ }
+ renderADMLPresentationContents() {
+ return `<dropdownList refId="${this.name}" />`;
+ }
+}
+const IntQ = {
+ Q: `(number) @value`,
+ value(matches) {
+ const match = matches[0];
+ if (!match) {
+ return undefined;
+ }
+ const value = match.captures.filter(c => c.name === 'value')[0]?.node.text;
+ if (!value) {
+ throw new Error(`Missing required 'value' property.`);
+ }
+ return parseInt(value);
+ }
+};
+const StringQ = {
+ Q: `[
+ (string (string_fragment) @value)
+ (call_expression function: (identifier) @localizeFn arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) (#eq? @localizeFn localize))
+ ]`,
+ value(matches) {
+ const match = matches[0];
+ if (!match) {
+ return undefined;
+ }
+ const value = match.captures.filter(c => c.name === 'value')[0]?.node.text;
+ if (!value) {
+ throw new Error(`Missing required 'value' property.`);
+ }
+ const nlsKey = match.captures.filter(c => c.name === 'nlsKey')[0]?.node.text;
+ if (nlsKey) {
+ return { value, nlsKey };
+ }
+ else {
+ return value;
+ }
+ }
+};
+const StringArrayQ = {
+ Q: `(array ${StringQ.Q})`,
+ value(matches) {
+ if (matches.length === 0) {
+ return undefined;
+ }
+ return matches.map(match => {
+ return StringQ.value([match]);
+ });
+ }
+};
+function getProperty(qtype, node, key) {
+ const query = new Parser.Query(typescript, `(
+ (pair
+ key: [(property_identifier)(string)] @key
+ value: ${qtype.Q}
+ )
+ (#eq? @key ${key})
+ )`);
+ return qtype.value(query.matches(node));
+}
+function getIntProperty(node, key) {
+ return getProperty(IntQ, node, key);
+}
+function getStringProperty(node, key) {
+ return getProperty(StringQ, node, key);
+}
+function getStringArrayProperty(node, key) {
+ return getProperty(StringArrayQ, node, key);
+}
+// TODO: add more policy types
+const PolicyTypes = [
+ BooleanPolicy,
+ IntPolicy,
+ StringEnumPolicy,
+ StringPolicy,
+];
+function getPolicy(moduleName, configurationNode, settingNode, policyNode, categories) {
+ const name = getStringProperty(policyNode, 'name');
+ if (!name) {
+ throw new Error(`Missing required 'name' property.`);
+ }
+ else if (isNlsString(name)) {
+ throw new Error(`Property 'name' should be a literal string.`);
+ }
+ const categoryName = getStringProperty(configurationNode, 'title');
+ if (!categoryName) {
+ throw new Error(`Missing required 'title' property.`);
+ }
+ else if (!isNlsString(categoryName)) {
+ throw new Error(`Property 'title' should be localized.`);
+ }
+ const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`;
+ let category = categories.get(categoryKey);
+ if (!category) {
+ category = { moduleName, name: categoryName };
+ categories.set(categoryKey, category);
+ }
+ const minimumVersion = getStringProperty(policyNode, 'minimumVersion');
+ if (!minimumVersion) {
+ throw new Error(`Missing required 'minimumVersion' property.`);
+ }
+ else if (isNlsString(minimumVersion)) {
+ throw new Error(`Property 'minimumVersion' should be a literal string.`);
+ }
+ const description = getStringProperty(settingNode, 'description');
+ if (!description) {
+ throw new Error(`Missing required 'description' property.`);
+ }
+ if (!isNlsString(description)) {
+ throw new Error(`Property 'description' should be localized.`);
+ }
+ let result;
+ for (const policyType of PolicyTypes) {
+ if (result = policyType.from(name, category, minimumVersion, description, moduleName, settingNode)) {
+ break;
+ }
+ }
+ if (!result) {
+ throw new Error(`Failed to parse policy '${name}'.`);
+ }
+ return result;
+}
+function getPolicies(moduleName, node) {
+ const query = new Parser.Query(typescript, `
+ (
+ (call_expression
+ function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration)
+ arguments: (arguments (object (pair
+ key: [(property_identifier)(string)] @propertiesKey (#eq? @propertiesKey properties)
+ value: (object (pair
+ key: [(property_identifier)(string)]
+ value: (object (pair
+ key: [(property_identifier)(string)] @policyKey (#eq? @policyKey policy)
+ value: (object) @policy
+ )) @setting
+ ))
+ )) @configuration)
+ )
+ )
+ `);
+ const categories = new Map();
+ return query.matches(node).map(m => {
+ const configurationNode = m.captures.filter(c => c.name === 'configuration')[0].node;
+ const settingNode = m.captures.filter(c => c.name === 'setting')[0].node;
+ const policyNode = m.captures.filter(c => c.name === 'policy')[0].node;
+ return getPolicy(moduleName, configurationNode, settingNode, policyNode, categories);
+ });
+}
+async function getFiles(root) {
+ return new Promise((c, e) => {
+ const result = [];
+ const rg = (0, child_process_1.spawn)(ripgrep_1.rgPath, ['-l', 'registerConfiguration\\(', '-g', 'src/**/*.ts', '-g', '!src/**/test/**', root]);
+ const stream = byline(rg.stdout.setEncoding('utf8'));
+ stream.on('data', path => result.push(path));
+ stream.on('error', err => e(err));
+ stream.on('end', () => c(result));
+ });
+}
+function renderADMX(regKey, versions, categories, policies) {
+ versions = versions.map(v => v.replace(/\./g, '_'));
+ return `<?xml version="1.0" encoding="utf-8"?>
+<policyDefinitions revision="1.1" schemaVersion="1.0">
+ <policyNamespaces>
+ <target prefix="${regKey}" namespace="Microsoft.Policies.${regKey}" />
+ </policyNamespaces>
+ <resources minRequiredRevision="1.0" />
+ <supportedOn>
+ <definitions>
+ ${versions.map(v => `<definition name="Supported_${v}" displayName="$(string.Supported_${v})" />`).join(`\n `)}
+ </definitions>
+ </supportedOn>
+ <categories>
+ <category displayName="$(string.Application)" name="Application" />
+ ${categories.map(c => `<category displayName="$(string.Category_${c.name.nlsKey})" name="${c.name.nlsKey}"><parentCategory ref="Application" /></category>`).join(`\n `)}
+ </categories>
+ <policies>
+ ${policies.map(p => p.renderADMX(regKey)).flat().join(`\n `)}
+ </policies>
+</policyDefinitions>
+`;
+}
+function renderADML(appName, versions, categories, policies, translations) {
+ return `<?xml version="1.0" encoding="utf-8"?>
+<policyDefinitionResources revision="1.0" schemaVersion="1.0">
+ <displayName />
+ <description />
+ <resources>
+ <stringTable>
+ <string id="Application">${appName}</string>
+ ${versions.map(v => `<string id="Supported_${v.replace(/\./g, '_')}">${appName} &gt;= ${v}</string>`)}
+ ${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations))}
+ ${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)}
+ </stringTable>
+ <presentationTable>
+ ${policies.map(p => p.renderADMLPresentation()).join(`\n `)}
+ </presentationTable>
+ </resources>
+</policyDefinitionResources>
+`;
+}
+function renderGP(policies, translations) {
+ const appName = product.nameLong;
+ const regKey = product.win32RegValueName;
+ const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort();
+ const categories = [...new Set(policies.map(p => p.category))];
+ return {
+ admx: renderADMX(regKey, versions, categories, policies),
+ adml: [
+ { languageId: 'en-us', contents: renderADML(appName, versions, categories, policies) },
+ ...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderADML(appName, versions, categories, policies, languageTranslations) }))
+ ]
+ };
+}
+const Languages = {
+ 'fr': 'fr-fr',
+ 'it': 'it-it',
+ 'de': 'de-de',
+ 'es': 'es-es',
+ 'ru': 'ru-ru',
+ 'zh-hans': 'zh-cn',
+ 'zh-hant': 'zh-tw',
+ 'ja': 'ja-jp',
+ 'ko': 'ko-kr',
+ 'cs': 'cs-cz',
+ 'pt-br': 'pt-br',
+ 'tr': 'tr-tr',
+ 'pl': 'pl-pl',
+};
+async function getLatestStableVersion(updateUrl) {
+ const res = await (0, node_fetch_1.default)(`${updateUrl}/api/update/darwin/stable/latest`);
+ const { name: version } = await res.json();
+ return version;
+}
+async function getNLS(resourceUrlTemplate, languageId, version) {
+ const resource = {
+ publisher: 'ms-ceintl',
+ name: `vscode-language-pack-${languageId}`,
+ version,
+ path: 'extension/translations/main.i18n.json'
+ };
+ const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key]);
+ const res = await (0, node_fetch_1.default)(url);
+ const { contents: result } = await res.json();
+ return result;
+}
+async function parsePolicies() {
+ const parser = new Parser();
+ parser.setLanguage(typescript);
+ const files = await getFiles(process.cwd());
+ const base = path.join(process.cwd(), 'src');
+ const policies = [];
+ for (const file of files) {
+ const moduleName = path.relative(base, file).replace(/\.ts$/i, '').replace(/\\/g, '/');
+ const contents = await fs_1.promises.readFile(file, { encoding: 'utf8' });
+ const tree = parser.parse(contents);
+ policies.push(...getPolicies(moduleName, tree.rootNode));
+ }
+ return policies;
+}
+async function getTranslations() {
+ const updateUrl = product.updateUrl;
+ if (!updateUrl) {
+ console.warn(`Skipping policy localization: No 'updateUrl' found in 'product.json'.`);
+ return [];
+ }
+ const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate;
+ if (!resourceUrlTemplate) {
+ console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`);
+ return [];
+ }
+ const version = await getLatestStableVersion(updateUrl);
+ const languageIds = Object.keys(Languages);
+ return await Promise.all(languageIds.map(languageId => getNLS(resourceUrlTemplate, languageId, version)
+ .then(languageTranslations => ({ languageId, languageTranslations }))));
+}
+async function main() {
+ const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
+ const { admx, adml } = await renderGP(policies, translations);
+ const root = '.build/policies/win32';
+ await fs_1.promises.rm(root, { recursive: true, force: true });
+ await fs_1.promises.mkdir(root, { recursive: true });
+ await fs_1.promises.writeFile(path.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n'));
+ for (const { languageId, contents } of adml) {
+ const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId]);
+ await fs_1.promises.mkdir(languagePath, { recursive: true });
+ await fs_1.promises.writeFile(path.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n'));
+ }
+}
+if (require.main === module) {
+ main().catch(err => {
+ console.error(err);
+ process.exit(1);
+ });
+}
diff --git a/build/lib/policies.ts b/build/lib/policies.ts
new file mode 100644
index 00000000000..62ea4d561e5
--- /dev/null
+++ b/build/lib/policies.ts
@@ -0,0 +1,674 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { spawn } from 'child_process';
+import { promises as fs } from 'fs';
+import * as path from 'path';
+import * as byline from 'byline';
+import { rgPath } from '@vscode/ripgrep';
+import * as Parser from 'tree-sitter';
+import fetch from 'node-fetch';
+const { typescript } = require('tree-sitter-typescript');
+const product = require('../../product.json');
+
+type NlsString = { value: string; nlsKey: string };
+
+function isNlsString(value: string | NlsString | undefined): value is NlsString {
+ return value ? typeof value !== 'string' : false;
+}
+
+function isStringArray(value: (string | NlsString)[]): value is string[] {
+ return !value.some(s => isNlsString(s));
+}
+
+function isNlsStringArray(value: (string | NlsString)[]): value is NlsString[] {
+ return value.every(s => isNlsString(s));
+}
+
+interface Category {
+ readonly moduleName: string;
+ readonly name: NlsString;
+}
+
+enum PolicyType {
+ StringEnum
+}
+
+interface Policy {
+ readonly category: Category;
+ readonly minimumVersion: string;
+ renderADMX(regKey: string): string[];
+ renderADMLStrings(translations?: LanguageTranslations): string[];
+ renderADMLPresentation(): string;
+}
+
+function renderADMLString(prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string {
+ let value: string | undefined;
+
+ if (translations) {
+ const moduleTranslations = translations[moduleName];
+
+ if (moduleTranslations) {
+ value = moduleTranslations[nlsString.nlsKey];
+ }
+ }
+
+ if (!value) {
+ value = nlsString.value;
+ }
+
+ return `<string id="${prefix}_${nlsString.nlsKey}">${value}</string>`;
+}
+
+abstract class BasePolicy implements Policy {
+ constructor(
+ protected policyType: PolicyType,
+ protected name: string,
+ readonly category: Category,
+ readonly minimumVersion: string,
+ protected description: NlsString,
+ protected moduleName: string,
+ ) { }
+
+ protected renderADMLString(nlsString: NlsString, translations?: LanguageTranslations): string {
+ return renderADMLString(this.name, this.moduleName, nlsString, translations);
+ }
+
+ renderADMX(regKey: string) {
+ return [
+ `<policy name="${this.name}" class="Both" displayName="$(string.${this.name})" explainText="$(string.${this.name}_${this.description.nlsKey})" key="Software\\Policies\\Microsoft\\${regKey}" presentation="$(presentation.${this.name})">`,
+ ` <parentCategory ref="${this.category.name.nlsKey}" />`,
+ ` <supportedOn ref="Supported_${this.minimumVersion.replace(/\./g, '_')}" />`,
+ ` <elements>`,
+ ...this.renderADMXElements(),
+ ` </elements>`,
+ `</policy>`
+ ];
+ }
+
+ protected abstract renderADMXElements(): string[];
+
+ renderADMLStrings(translations?: LanguageTranslations) {
+ return [
+ `<string id="${this.name}">${this.name}</string>`,
+ this.renderADMLString(this.description, translations)
+ ];
+ }
+
+ renderADMLPresentation(): string {
+ return `<presentation id="${this.name}">${this.renderADMLPresentationContents()}</presentation>`;
+ }
+
+ protected abstract renderADMLPresentationContents(): string;
+}
+
+class BooleanPolicy extends BasePolicy {
+
+ static from(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ settingNode: Parser.SyntaxNode
+ ): BooleanPolicy | undefined {
+ const type = getStringProperty(settingNode, 'type');
+
+ if (type !== 'boolean') {
+ return undefined;
+ }
+
+ return new BooleanPolicy(name, category, minimumVersion, description, moduleName);
+ }
+
+ private constructor(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ ) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ }
+
+ protected renderADMXElements(): string[] {
+ return [
+ `<boolean id="${this.name}" valueName="${this.name}">`,
+ ` <trueValue><decimal value="1" /></trueValue><falseValue><decimal value="0" /></falseValue>`,
+ `</boolean>`
+ ];
+ }
+
+ renderADMLPresentationContents() {
+ return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
+ }
+}
+
+class IntPolicy extends BasePolicy {
+
+ static from(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ settingNode: Parser.SyntaxNode
+ ): IntPolicy | undefined {
+ const type = getStringProperty(settingNode, 'type');
+
+ if (type !== 'number') {
+ return undefined;
+ }
+
+ const defaultValue = getIntProperty(settingNode, 'default');
+
+ if (typeof defaultValue === 'undefined') {
+ throw new Error(`Missing required 'default' property.`);
+ }
+
+ return new IntPolicy(name, category, minimumVersion, description, moduleName, defaultValue);
+ }
+
+ private constructor(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ protected readonly defaultValue: number,
+ ) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ }
+
+ protected renderADMXElements(): string[] {
+ return [
+ `<decimal id="${this.name}" valueName="${this.name}" />`
+ // `<decimal id="Quarantine_PurgeItemsAfterDelay" valueName="PurgeItemsAfterDelay" minValue="0" maxValue="10000000" />`
+ ];
+ }
+
+ renderADMLPresentationContents() {
+ return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
+ }
+}
+
+class StringPolicy extends BasePolicy {
+
+ static from(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ settingNode: Parser.SyntaxNode
+ ): StringPolicy | undefined {
+ const type = getStringProperty(settingNode, 'type');
+
+ if (type !== 'string') {
+ return undefined;
+ }
+
+ return new StringPolicy(name, category, minimumVersion, description, moduleName);
+ }
+
+ private constructor(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ ) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ }
+
+ protected renderADMXElements(): string[] {
+ return [`<text id="${this.name}" valueName="${this.name}" required="true" />`];
+ }
+
+ renderADMLPresentationContents() {
+ return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
+ }
+}
+
+class StringEnumPolicy extends BasePolicy {
+
+ static from(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ settingNode: Parser.SyntaxNode
+ ): StringEnumPolicy | undefined {
+ const type = getStringProperty(settingNode, 'type');
+
+ if (type !== 'string') {
+ return undefined;
+ }
+
+ const enum_ = getStringArrayProperty(settingNode, 'enum');
+
+ if (!enum_) {
+ return undefined;
+ }
+
+ if (!isStringArray(enum_)) {
+ throw new Error(`Property 'enum' should not be localized.`);
+ }
+
+ const enumDescriptions = getStringArrayProperty(settingNode, 'enumDescriptions');
+
+ if (!enumDescriptions) {
+ throw new Error(`Missing required 'enumDescriptions' property.`);
+ } else if (!isNlsStringArray(enumDescriptions)) {
+ throw new Error(`Property 'enumDescriptions' should be localized.`);
+ }
+
+ return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions);
+ }
+
+ private constructor(
+ name: string,
+ category: Category,
+ minimumVersion: string,
+ description: NlsString,
+ moduleName: string,
+ protected enum_: string[],
+ protected enumDescriptions: NlsString[],
+ ) {
+ super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
+ }
+
+ protected renderADMXElements(): string[] {
+ return [
+ `<enum id="${this.name}" valueName="${this.name}">`,
+ ...this.enum_.map((value, index) => ` <item displayName="$(string.${this.name}_${this.enumDescriptions[index].nlsKey})"><value><string>${value}</string></value></item>`),
+ `</enum>`
+ ];
+ }
+
+ renderADMLStrings(translations?: LanguageTranslations) {
+ return [
+ ...super.renderADMLStrings(translations),
+ ...this.enumDescriptions.map(e => this.renderADMLString(e, translations))
+ ];
+ }
+
+ renderADMLPresentationContents() {
+ return `<dropdownList refId="${this.name}" />`;
+ }
+}
+
+interface QType<T> {
+ Q: string;
+ value(matches: Parser.QueryMatch[]): T | undefined;
+}
+
+const IntQ: QType<number> = {
+ Q: `(number) @value`,
+
+ value(matches: Parser.QueryMatch[]): number | undefined {
+ const match = matches[0];
+
+ if (!match) {
+ return undefined;
+ }
+
+ const value = match.captures.filter(c => c.name === 'value')[0]?.node.text;
+
+ if (!value) {
+ throw new Error(`Missing required 'value' property.`);
+ }
+
+ return parseInt(value);
+ }
+};
+
+const StringQ: QType<string | NlsString> = {
+ Q: `[
+ (string (string_fragment) @value)
+ (call_expression function: (identifier) @localizeFn arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) (#eq? @localizeFn localize))
+ ]`,
+
+ value(matches: Parser.QueryMatch[]): string | NlsString | undefined {
+ const match = matches[0];
+
+ if (!match) {
+ return undefined;
+ }
+
+ const value = match.captures.filter(c => c.name === 'value')[0]?.node.text;
+
+ if (!value) {
+ throw new Error(`Missing required 'value' property.`);
+ }
+
+ const nlsKey = match.captures.filter(c => c.name === 'nlsKey')[0]?.node.text;
+
+ if (nlsKey) {
+ return { value, nlsKey };
+ } else {
+ return value;
+ }
+ }
+};
+
+const StringArrayQ: QType<(string | NlsString)[]> = {
+ Q: `(array ${StringQ.Q})`,
+
+ value(matches: Parser.QueryMatch[]): (string | NlsString)[] | undefined {
+ if (matches.length === 0) {
+ return undefined;
+ }
+
+ return matches.map(match => {
+ return StringQ.value([match]) as string | NlsString;
+ });
+ }
+};
+
+function getProperty<T>(qtype: QType<T>, node: Parser.SyntaxNode, key: string): T | undefined {
+ const query = new Parser.Query(
+ typescript,
+ `(
+ (pair
+ key: [(property_identifier)(string)] @key
+ value: ${qtype.Q}
+ )
+ (#eq? @key ${key})
+ )`
+ );
+
+ return qtype.value(query.matches(node));
+}
+
+function getIntProperty(node: Parser.SyntaxNode, key: string): number | undefined {
+ return getProperty(IntQ, node, key);
+}
+
+function getStringProperty(node: Parser.SyntaxNode, key: string): string | NlsString | undefined {
+ return getProperty(StringQ, node, key);
+}
+
+function getStringArrayProperty(node: Parser.SyntaxNode, key: string): (string | NlsString)[] | undefined {
+ return getProperty(StringArrayQ, node, key);
+}
+
+// TODO: add more policy types
+const PolicyTypes = [
+ BooleanPolicy,
+ IntPolicy,
+ StringEnumPolicy,
+ StringPolicy,
+];
+
+function getPolicy(
+ moduleName: string,
+ configurationNode: Parser.SyntaxNode,
+ settingNode: Parser.SyntaxNode,
+ policyNode: Parser.SyntaxNode,
+ categories: Map<string, Category>
+): Policy {
+ const name = getStringProperty(policyNode, 'name');
+
+ if (!name) {
+ throw new Error(`Missing required 'name' property.`);
+ } else if (isNlsString(name)) {
+ throw new Error(`Property 'name' should be a literal string.`);
+ }
+
+ const categoryName = getStringProperty(configurationNode, 'title');
+
+ if (!categoryName) {
+ throw new Error(`Missing required 'title' property.`);
+ } else if (!isNlsString(categoryName)) {
+ throw new Error(`Property 'title' should be localized.`);
+ }
+
+ const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`;
+ let category = categories.get(categoryKey);
+
+ if (!category) {
+ category = { moduleName, name: categoryName };
+ categories.set(categoryKey, category);
+ }
+
+ const minimumVersion = getStringProperty(policyNode, 'minimumVersion');
+
+ if (!minimumVersion) {
+ throw new Error(`Missing required 'minimumVersion' property.`);
+ } else if (isNlsString(minimumVersion)) {
+ throw new Error(`Property 'minimumVersion' should be a literal string.`);
+ }
+
+ const description = getStringProperty(settingNode, 'description');
+
+ if (!description) {
+ throw new Error(`Missing required 'description' property.`);
+ } if (!isNlsString(description)) {
+ throw new Error(`Property 'description' should be localized.`);
+ }
+
+ let result: Policy | undefined;
+
+ for (const policyType of PolicyTypes) {
+ if (result = policyType.from(name, category, minimumVersion, description, moduleName, settingNode)) {
+ break;
+ }
+ }
+
+ if (!result) {
+ throw new Error(`Failed to parse policy '${name}'.`);
+ }
+
+ return result;
+}
+
+function getPolicies(moduleName: string, node: Parser.SyntaxNode): Policy[] {
+ const query = new Parser.Query(typescript, `
+ (
+ (call_expression
+ function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration)
+ arguments: (arguments (object (pair
+ key: [(property_identifier)(string)] @propertiesKey (#eq? @propertiesKey properties)
+ value: (object (pair
+ key: [(property_identifier)(string)]
+ value: (object (pair
+ key: [(property_identifier)(string)] @policyKey (#eq? @policyKey policy)
+ value: (object) @policy
+ )) @setting
+ ))
+ )) @configuration)
+ )
+ )
+ `);
+
+ const categories = new Map<string, Category>();
+
+ return query.matches(node).map(m => {
+ const configurationNode = m.captures.filter(c => c.name === 'configuration')[0].node;
+ const settingNode = m.captures.filter(c => c.name === 'setting')[0].node;
+ const policyNode = m.captures.filter(c => c.name === 'policy')[0].node;
+ return getPolicy(moduleName, configurationNode, settingNode, policyNode, categories);
+ });
+}
+
+async function getFiles(root: string): Promise<string[]> {
+ return new Promise((c, e) => {
+ const result: string[] = [];
+ const rg = spawn(rgPath, ['-l', 'registerConfiguration\\(', '-g', 'src/**/*.ts', '-g', '!src/**/test/**', root]);
+ const stream = byline(rg.stdout.setEncoding('utf8'));
+ stream.on('data', path => result.push(path));
+ stream.on('error', err => e(err));
+ stream.on('end', () => c(result));
+ });
+}
+
+function renderADMX(regKey: string, versions: string[], categories: Category[], policies: Policy[]) {
+ versions = versions.map(v => v.replace(/\./g, '_'));
+
+ return `<?xml version="1.0" encoding="utf-8"?>
+<policyDefinitions revision="1.1" schemaVersion="1.0">
+ <policyNamespaces>
+ <target prefix="${regKey}" namespace="Microsoft.Policies.${regKey}" />
+ </policyNamespaces>
+ <resources minRequiredRevision="1.0" />
+ <supportedOn>
+ <definitions>
+ ${versions.map(v => `<definition name="Supported_${v}" displayName="$(string.Supported_${v})" />`).join(`\n `)}
+ </definitions>
+ </supportedOn>
+ <categories>
+ <category displayName="$(string.Application)" name="Application" />
+ ${categories.map(c => `<category displayName="$(string.Category_${c.name.nlsKey})" name="${c.name.nlsKey}"><parentCategory ref="Application" /></category>`).join(`\n `)}
+ </categories>
+ <policies>
+ ${policies.map(p => p.renderADMX(regKey)).flat().join(`\n `)}
+ </policies>
+</policyDefinitions>
+`;
+}
+
+function renderADML(appName: string, versions: string[], categories: Category[], policies: Policy[], translations?: LanguageTranslations) {
+ return `<?xml version="1.0" encoding="utf-8"?>
+<policyDefinitionResources revision="1.0" schemaVersion="1.0">
+ <displayName />
+ <description />
+ <resources>
+ <stringTable>
+ <string id="Application">${appName}</string>
+ ${versions.map(v => `<string id="Supported_${v.replace(/\./g, '_')}">${appName} &gt;= ${v}</string>`)}
+ ${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations))}
+ ${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)}
+ </stringTable>
+ <presentationTable>
+ ${policies.map(p => p.renderADMLPresentation()).join(`\n `)}
+ </presentationTable>
+ </resources>
+</policyDefinitionResources>
+`;
+}
+
+function renderGP(policies: Policy[], translations: Translations) {
+ const appName = product.nameLong;
+ const regKey = product.win32RegValueName;
+
+ const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort();
+ const categories = [...new Set(policies.map(p => p.category))];
+
+ return {
+ admx: renderADMX(regKey, versions, categories, policies),
+ adml: [
+ { languageId: 'en-us', contents: renderADML(appName, versions, categories, policies) },
+ ...translations.map(({ languageId, languageTranslations }) =>
+ ({ languageId, contents: renderADML(appName, versions, categories, policies, languageTranslations) }))
+ ]
+ };
+}
+
+const Languages = {
+ 'fr': 'fr-fr',
+ 'it': 'it-it',
+ 'de': 'de-de',
+ 'es': 'es-es',
+ 'ru': 'ru-ru',
+ 'zh-hans': 'zh-cn',
+ 'zh-hant': 'zh-tw',
+ 'ja': 'ja-jp',
+ 'ko': 'ko-kr',
+ 'cs': 'cs-cz',
+ 'pt-br': 'pt-br',
+ 'tr': 'tr-tr',
+ 'pl': 'pl-pl',
+};
+
+type LanguageTranslations = { [moduleName: string]: { [nlsKey: string]: string } };
+type Translations = { languageId: string; languageTranslations: LanguageTranslations }[];
+
+async function getLatestStableVersion(updateUrl: string) {
+ const res = await fetch(`${updateUrl}/api/update/darwin/stable/latest`);
+ const { name: version } = await res.json() as { name: string };
+ return version;
+}
+
+async function getNLS(resourceUrlTemplate: string, languageId: string, version: string) {
+ const resource = {
+ publisher: 'ms-ceintl',
+ name: `vscode-language-pack-${languageId}`,
+ version,
+ path: 'extension/translations/main.i18n.json'
+ };
+
+ const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key as keyof typeof resource]);
+ const res = await fetch(url);
+ const { contents: result } = await res.json() as { contents: LanguageTranslations };
+ return result;
+}
+
+async function parsePolicies(): Promise<Policy[]> {
+ const parser = new Parser();
+ parser.setLanguage(typescript);
+
+ const files = await getFiles(process.cwd());
+ const base = path.join(process.cwd(), 'src');
+ const policies = [];
+
+ for (const file of files) {
+ const moduleName = path.relative(base, file).replace(/\.ts$/i, '').replace(/\\/g, '/');
+ const contents = await fs.readFile(file, { encoding: 'utf8' });
+ const tree = parser.parse(contents);
+ policies.push(...getPolicies(moduleName, tree.rootNode));
+ }
+
+ return policies;
+}
+
+async function getTranslations(): Promise<Translations> {
+ const updateUrl = product.updateUrl;
+
+ if (!updateUrl) {
+ console.warn(`Skipping policy localization: No 'updateUrl' found in 'product.json'.`);
+ return [];
+ }
+
+ const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate;
+
+ if (!resourceUrlTemplate) {
+ console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`);
+ return [];
+ }
+
+ const version = await getLatestStableVersion(updateUrl);
+ const languageIds = Object.keys(Languages);
+
+ return await Promise.all(languageIds.map(
+ languageId => getNLS(resourceUrlTemplate, languageId, version)
+ .then(languageTranslations => ({ languageId, languageTranslations }))
+ ));
+}
+
+async function main() {
+ const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
+ const { admx, adml } = await renderGP(policies, translations);
+
+ const root = '.build/policies/win32';
+ await fs.rm(root, { recursive: true, force: true });
+ await fs.mkdir(root, { recursive: true });
+
+ await fs.writeFile(path.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n'));
+
+ for (const { languageId, contents } of adml) {
+ const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId as keyof typeof Languages]);
+ await fs.mkdir(languagePath, { recursive: true });
+ await fs.writeFile(path.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n'));
+ }
+}
+
+if (require.main === module) {
+ main().catch(err => {
+ console.error(err);
+ process.exit(1);
+ });
+}
diff --git a/build/lib/tsb/builder.js b/build/lib/tsb/builder.js
index f0e1958df7e..cb700a54077 100644
--- a/build/lib/tsb/builder.js
+++ b/build/lib/tsb/builder.js
@@ -286,7 +286,7 @@ function createTypeScriptBuilder(config, projectFile, cmd) {
if (config.verbose) {
const headNow = process.memoryUsage().heapUsed;
const MB = 1024 * 1024;
- log('[tsb]', 'time:', colors.yellow((Date.now() - t1) + 'ms'), 'mem:', colors.cyan(Math.ceil(headNow / MB) + 'MB'), colors.bgcyan('delta: ' + Math.ceil((headNow - headUsed) / MB)));
+ log('[tsb]', 'time:', colors.yellow((Date.now() - t1) + 'ms'), 'mem:', colors.cyan(Math.ceil(headNow / MB) + 'MB'), colors.bgCyan('delta: ' + Math.ceil((headNow - headUsed) / MB)));
headUsed = headNow;
}
});
diff --git a/build/lib/tsb/builder.ts b/build/lib/tsb/builder.ts
index 2f8753dd119..d5bec6ee97b 100644
--- a/build/lib/tsb/builder.ts
+++ b/build/lib/tsb/builder.ts
@@ -360,7 +360,7 @@ export function createTypeScriptBuilder(config: IConfiguration, projectFile: str
const MB = 1024 * 1024;
log('[tsb]',
'time:', colors.yellow((Date.now() - t1) + 'ms'),
- 'mem:', colors.cyan(Math.ceil(headNow / MB) + 'MB'), colors.bgcyan('delta: ' + Math.ceil((headNow - headUsed) / MB))
+ 'mem:', colors.cyan(Math.ceil(headNow / MB) + 'MB'), colors.bgCyan('delta: ' + Math.ceil((headNow - headUsed) / MB))
);
headUsed = headNow;
}
diff --git a/build/lib/watch/.gitignore b/build/lib/watch/.gitignore
deleted file mode 100644
index d777dcaa9d6..00000000000
--- a/build/lib/watch/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.yarnrc \ No newline at end of file
diff --git a/build/lib/watch/package.json b/build/lib/watch/package.json
deleted file mode 100644
index e2e4f552025..00000000000
--- a/build/lib/watch/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "watch",
- "version": "1.0.0",
- "description": "",
- "author": "Microsoft ",
- "private": true,
- "license": "MIT",
- "devDependencies": {},
- "dependencies": {
- "vscode-gulp-watch": "^5.0.3"
- }
-}
diff --git a/build/lib/watch/yarn.lock b/build/lib/watch/yarn.lock
deleted file mode 100644
index 258c0edadad..00000000000
--- a/build/lib/watch/yarn.lock
+++ /dev/null
@@ -1,400 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-ansi-colors@4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
- integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
-
-ansi-colors@^1.0.1:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9"
- integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==
- dependencies:
- ansi-wrap "^0.1.0"
-
-ansi-gray@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251"
- integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE=
- dependencies:
- ansi-wrap "0.1.0"
-
-ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
- integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768=
-
-anymatch@^3.1.1, anymatch@~3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
- integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
- dependencies:
- normalize-path "^3.0.0"
- picomatch "^2.0.4"
-
-arr-diff@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
- integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=
-
-arr-union@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
- integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
-
-assign-symbols@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
- integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
-
-binary-extensions@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
- integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
-
-braces@~3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
- integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
- dependencies:
- fill-range "^7.0.1"
-
-chokidar@3.5.1:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
- integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
- dependencies:
- anymatch "~3.1.1"
- braces "~3.0.2"
- glob-parent "~5.1.0"
- is-binary-path "~2.1.0"
- is-glob "~4.0.1"
- normalize-path "~3.0.0"
- readdirp "~3.5.0"
- optionalDependencies:
- fsevents "~2.3.1"
-
-clone-buffer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
- integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg=
-
-clone-stats@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
- integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=
-
-clone@^2.1.1:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
- integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
-
-cloneable-readable@^1.0.0:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec"
- integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==
- dependencies:
- inherits "^2.0.1"
- process-nextick-args "^2.0.0"
- readable-stream "^2.3.5"
-
-color-support@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
- integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
-
-core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-extend-shallow@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
- integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=
- dependencies:
- assign-symbols "^1.0.0"
- is-extendable "^1.0.1"
-
-fancy-log@^1.3.3:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7"
- integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==
- dependencies:
- ansi-gray "^0.1.1"
- color-support "^1.1.3"
- parse-node-version "^1.0.0"
- time-stamp "^1.0.0"
-
-fill-range@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
- integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
- dependencies:
- to-regex-range "^5.0.1"
-
-first-chunk-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70"
- integrity sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=
- dependencies:
- readable-stream "^2.0.2"
-
-fsevents@~2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f"
- integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==
-
-glob-parent@^5.1.1, glob-parent@~5.1.0:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
- integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
- dependencies:
- is-glob "^4.0.1"
-
-graceful-fs@^4.1.2:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
- integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
-
-inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-is-binary-path@~2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
- integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
- dependencies:
- binary-extensions "^2.0.0"
-
-is-extendable@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4"
- integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==
- dependencies:
- is-plain-object "^2.0.4"
-
-is-extglob@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
- integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
-
-is-glob@^4.0.1, is-glob@~4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
- integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
- dependencies:
- is-extglob "^2.1.1"
-
-is-number@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
- integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-
-is-plain-object@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
- integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
- dependencies:
- isobject "^3.0.1"
-
-is-utf8@^0.2.0, is-utf8@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
- integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
-
-isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-isobject@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
- integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
-
-normalize-path@^3.0.0, normalize-path@~3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
- integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-
-object-assign@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-parse-node-version@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b"
- integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==
-
-picomatch@^2.0.4, picomatch@^2.2.1:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
- integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
-
-pify@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
- integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
-
-plugin-error@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c"
- integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==
- dependencies:
- ansi-colors "^1.0.1"
- arr-diff "^4.0.0"
- arr-union "^3.1.0"
- extend-shallow "^3.0.2"
-
-process-nextick-args@^2.0.0, process-nextick-args@~2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
- integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-readable-stream@^2.0.2, readable-stream@^2.3.5:
- version "2.3.7"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
- integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-readable-stream@^3.6.0:
- version "3.6.0"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
- integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
- dependencies:
- inherits "^2.0.3"
- string_decoder "^1.1.1"
- util-deprecate "^1.0.1"
-
-readdirp@~3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
- integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==
- dependencies:
- picomatch "^2.2.1"
-
-remove-trailing-separator@^1.0.1:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
- integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
-
-replace-ext@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
- integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
-
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safe-buffer@~5.2.0:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
- integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
-string_decoder@^1.1.1:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
- integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
- dependencies:
- safe-buffer "~5.2.0"
-
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
-strip-bom-buf@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572"
- integrity sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=
- dependencies:
- is-utf8 "^0.2.1"
-
-strip-bom-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
- integrity sha1-+H217yYT9paKpUWr/h7HKLaoKco=
- dependencies:
- first-chunk-stream "^2.0.0"
- strip-bom "^2.0.0"
-
-strip-bom@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
- integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
- dependencies:
- is-utf8 "^0.2.0"
-
-time-stamp@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3"
- integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=
-
-to-regex-range@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
- integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
- dependencies:
- is-number "^7.0.0"
-
-util-deprecate@^1.0.1, util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-vinyl-file@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-3.0.0.tgz#b104d9e4409ffa325faadd520642d0a3b488b365"
- integrity sha1-sQTZ5ECf+jJfqt1SBkLQo7SIs2U=
- dependencies:
- graceful-fs "^4.1.2"
- pify "^2.3.0"
- strip-bom-buf "^1.0.0"
- strip-bom-stream "^2.0.0"
- vinyl "^2.0.1"
-
-vinyl@^2.0.1, vinyl@^2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974"
- integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==
- dependencies:
- clone "^2.1.1"
- clone-buffer "^1.0.0"
- clone-stats "^1.0.0"
- cloneable-readable "^1.0.0"
- remove-trailing-separator "^1.0.1"
- replace-ext "^1.0.0"
-
-vscode-gulp-watch@^5.0.3:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/vscode-gulp-watch/-/vscode-gulp-watch-5.0.3.tgz#1ca1c03581d43692ecb1fe0b9afd4256faeb701b"
- integrity sha512-MTUp2yLE9CshhkNSNV58EQNxQSeF8lIj3mkXZX9a1vAk+EQNM2PAYdPUDSd/P/08W3PMHGznEiZyfK7JAjLosg==
- dependencies:
- ansi-colors "4.1.1"
- anymatch "^3.1.1"
- chokidar "3.5.1"
- fancy-log "^1.3.3"
- glob-parent "^5.1.1"
- normalize-path "^3.0.0"
- object-assign "^4.1.1"
- plugin-error "1.0.1"
- readable-stream "^3.6.0"
- vinyl "^2.2.0"
- vinyl-file "^3.0.0"