diff --git a/.travis.yml b/.travis.yml index cb271784ad9..8547e3081cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,7 +51,6 @@ install: script: - node_modules/.bin/gulp electron --silent - - node_modules/.bin/tsc -p ./src/tsconfig.monaco.json --noEmit - node_modules/.bin/gulp compile --silent --max_old_space_size=4096 - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --coverage --reporter dot; else ./scripts/test.sh --reporter dot; fi - ./scripts/test-integration.sh diff --git a/.yarnrc b/.yarnrc index d725d462bab..42f08fa0c02 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "2.0.0-beta.6" +target "1.7.12" runtime "electron" diff --git a/appveyor.yml b/appveyor.yml index 3ece36f7a3e..d9471f2a8f8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,6 @@ install: build_script: - yarn - .\node_modules\.bin\gulp electron - - .\node_modules\.bin\tsc -p .\src\tsconfig.monaco.json --noEmit - npm run compile test_script: diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index a2366ec1720..659ef8b3008 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -93,7 +93,7 @@ gulp.task('clean-minified-editor', util.rimraf('out-editor-min')); gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor')); gulp.task('clean-editor-esm', util.rimraf('out-editor-esm')); -gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro'], function() { +gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro'], function () { standalone.createESMSourcesAndResources({ entryPoints: [ 'vs/editor/editor.main', @@ -107,7 +107,7 @@ gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro'], fun } }); }); -gulp.task('compile-editor-esm', ['extract-editor-esm', 'clean-editor-distro'], function() { +gulp.task('compile-editor-esm', ['extract-editor-esm', 'clean-editor-distro'], function () { const result = cp.spawnSync(`node`, [`../node_modules/.bin/tsc`], { cwd: path.join(__dirname, '../out-editor-esm') }); @@ -235,3 +235,60 @@ function filterStream(testFunc) { this.emit('data', data); }); } + + +//#region monaco type checking + +function createTscCompileTask(watch) { + return () => { + const createReporter = require('./lib/reporter').createReporter; + + return new Promise((resolve, reject) => { + const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit']; + if (watch) { + args.push('-w'); + } + const child = cp.spawn(`node`, args, { + cwd: path.join(__dirname, '..'), + // stdio: [null, 'pipe', 'inherit'] + }); + let errors = []; + let reporter = createReporter(); + let report; + let magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings + + child.stdout.on('data', data => { + let str = String(data); + str = str.replace(magic, '').trim(); + if (str.indexOf('Starting compilation') >= 0 || str.indexOf('File change detected') >= 0) { + errors.length = 0; + report = reporter.end(false); + + } else if (str.indexOf('Compilation complete') >= 0) { + report.end(); + + } else if (str) { + let match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str); + if (match) { + // trying to massage the message so that it matches the gulp-tsb error messages + // e.g. src/vs/base/common/strings.ts(663,5): error TS2322: Type '1234' is not assignable to type 'string'. + let fullpath = path.join(root, match[1]); + let message = match[3]; + // @ts-ignore + reporter(fullpath + message); + } else { + // @ts-ignore + reporter(str); + } + } + }); + child.on('exit', resolve); + child.on('error', reject); + }); + }; +} + +gulp.task('monaco-typecheck-watch', createTscCompileTask(true)); +gulp.task('monaco-typecheck', createTscCompileTask(false)); + +//#endregion diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 6b4cdd2855f..d0504e1c66b 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -49,7 +49,6 @@ const indentationFilter = [ '!src/vs/base/common/marked/marked.js', '!src/vs/base/common/winjs.base.js', '!src/vs/base/node/terminateProcess.sh', - '!src/vs/base/node/ps-win.ps1', '!test/assert.js', // except specific folders diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index ff34bc6dd53..ff35e0a5a6f 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -72,7 +72,7 @@ const vscodeResources = [ 'out-build/paths.js', 'out-build/vs/**/*.{svg,png,cur,html}', 'out-build/vs/base/common/performance.js', - 'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,ps-win.ps1}', + 'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh}', 'out-build/vs/base/browser/ui/octiconLabel/octicons/**', 'out-build/vs/workbench/browser/media/*-theme.css', 'out-build/vs/workbench/electron-browser/bootstrap/**', @@ -275,7 +275,7 @@ function packageTask(platform, arch, opts) { const packageJsonStream = gulp.src(['package.json'], { base: '.' }) .pipe(json({ name, version })); - const settingsSearchBuildId = getBuildNumber(); + const settingsSearchBuildId = getSettingsSearchBuildId(packageJson); const date = new Date().toISOString(); const productJsonStream = gulp.src(['product.json'], { base: '.' }) .pipe(json({ commit, date, checksums, settingsSearchBuildId })); @@ -481,14 +481,12 @@ gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () = } if (!fs.existsSync(allConfigDetailsPath)) { - console.error(`configuration file at ${allConfigDetailsPath} does not exist`); - return; + throw new Error(`configuration file at ${allConfigDetailsPath} does not exist`); } - const settingsSearchBuildId = getBuildNumber(); + const settingsSearchBuildId = getSettingsSearchBuildId(packageJson); if (!settingsSearchBuildId) { - console.error('Failed to compute build number'); - return; + throw new Error('Failed to compute build number'); } return gulp.src(allConfigDetailsPath) @@ -500,76 +498,18 @@ gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () = })); }); -function getBuildNumber() { - const previous = getPreviousVersion(packageJson.version); - if (!previous) { - return 0; - } +function getSettingsSearchBuildId(packageJson) { + const previous = util.getPreviousVersion(packageJson.version); try { const out = cp.execSync(`git rev-list ${previous}..HEAD --count`); const count = parseInt(out.toString()); - return versionStringToNumber(packageJson.version) * 1e4 + count; + return util.versionStringToNumber(packageJson.version) * 1e4 + count; } catch (e) { - console.error('Could not determine build number: ' + e.toString()); - return 0; + throw new Error('Could not determine build number: ' + e.toString()); } } -/** - * Given 1.17.2, return 1.17.1 - * 1.18.0 => 1.17.2. - * 2.0.0 => 1.18.0 (or the highest 1.x) - */ -function getPreviousVersion(versionStr) { - function tagExists(tagName) { - try { - cp.execSync(`git rev-parse ${tagName}`, { stdio: 'ignore' }); - return true; - } catch (e) { - return false; - } - } - - function getLastTagFromBase(semverArr, componentToTest) { - const baseVersion = semverArr.join('.'); - if (!tagExists(baseVersion)) { - console.error('Failed to find tag for base version, ' + baseVersion); - return null; - } - - let goodTag; - do { - goodTag = semverArr.join('.'); - semverArr[componentToTest]++; - } while (tagExists(semverArr.join('.'))); - - return goodTag; - } - - const semverArr = versionStr.split('.'); - if (semverArr[2] > 0) { - semverArr[2]--; - return semverArr.join('.'); - } else if (semverArr[1] > 0) { - semverArr[1]--; - return getLastTagFromBase(semverArr, 2); - } else { - semverArr[0]--; - return getLastTagFromBase(semverArr, 1); - } -} - -function versionStringToNumber(versionStr) { - const semverRegex = /(\d+)\.(\d+)\.(\d+)/; - const match = versionStr.match(semverRegex); - if (!match) { - return 0; - } - - return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10); -} - // This task is only run for the MacOS build gulp.task('generate-vscode-configuration', () => { return new Promise((resolve, reject) => { @@ -601,8 +541,5 @@ gulp.task('generate-vscode-configuration', () => { clearTimeout(timer); reject(err); }); - }).catch(e => { - // Don't fail the build - console.error(e.toString()); }); }); diff --git a/build/lib/compilation.js b/build/lib/compilation.js index 61c178b392e..998ebb4f379 100644 --- a/build/lib/compilation.js +++ b/build/lib/compilation.js @@ -22,7 +22,7 @@ var rootDir = path.join(__dirname, '../../src'); var options = require('../../src/tsconfig.json').compilerOptions; options.verbose = false; options.sourceMap = true; -if (process.env['VSCODE_NO_SOURCEMAP']) { +if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry options.sourceMap = false; } options.rootDir = rootDir; diff --git a/build/lib/i18n.js b/build/lib/i18n.js index 6f5558001c4..61893ed8b1d 100644 --- a/build/lib/i18n.js +++ b/build/lib/i18n.js @@ -1083,7 +1083,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} }; } var externalId = externalExtensions[resource]; - if (!externalId) { + if (!externalId) { // internal extension: remove 'extensions/extensionId/' segnent var secondSlash = path.indexOf('/', firstSlash + 1); extPack.contents[path.substr(secondSlash + 1)] = file.messages; } diff --git a/build/lib/nls.js b/build/lib/nls.js index 7f2730ec891..a63d3699014 100644 --- a/build/lib/nls.js +++ b/build/lib/nls.js @@ -150,13 +150,16 @@ function isImportNode(node) { .filter(function (d) { return d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport; }) .map(function (d) { return d.importClause.namedBindings.name; }) .concat(importEqualsDeclarations.map(function (d) { return d.name; })) + // find read-only references to `nls` .map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); }) .flatten() .filter(function (r) { return !r.isWriteAccess; }) + // find the deepest call expressions AST nodes that contain those references .map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); }) .map(function (a) { return lazy(a).last(); }) .filter(function (n) { return !!n; }) .map(function (n) { return n; }) + // only `localize` calls .filter(function (n) { return n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === 'localize'; }); // `localize` named imports var allLocalizeImportDeclarations = importDeclarations diff --git a/build/lib/reporter.js b/build/lib/reporter.js index 93fd65351df..7dc3f50e038 100644 --- a/build/lib/reporter.js +++ b/build/lib/reporter.js @@ -34,7 +34,13 @@ catch (err) { } function log() { var errors = _.flatten(allErrors); - errors.map(function (err) { return util.log(util.colors.red('Error') + ": " + err); }); + var seen = new Set(); + errors.map(function (err) { + if (!seen.has(err)) { + seen.add(err); + util.log(util.colors.red('Error') + ": " + err); + } + }); var regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/; var messages = errors .map(function (err) { return regex.exec(err); }) @@ -80,4 +86,3 @@ function createReporter() { return ReportFunc; } exports.createReporter = createReporter; -; diff --git a/build/lib/reporter.ts b/build/lib/reporter.ts index e072a60bbfd..e4be8549ddb 100644 --- a/build/lib/reporter.ts +++ b/build/lib/reporter.ts @@ -11,7 +11,7 @@ import * as util from 'gulp-util'; import * as fs from 'fs'; import * as path from 'path'; -const allErrors: Error[][] = []; +const allErrors: string[][] = []; let startTime: number = null; let count = 0; @@ -42,7 +42,14 @@ try { function log(): void { const errors = _.flatten(allErrors); - errors.map(err => util.log(`${util.colors.red('Error')}: ${err}`)); + const seen = new Set(); + + errors.map(err => { + if (!seen.has(err)) { + seen.add(err); + util.log(`${util.colors.red('Error')}: ${err}`); + } + }); const regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/; const messages = errors @@ -61,17 +68,17 @@ function log(): void { } export interface IReporter { - (err: Error): void; + (err: string): void; hasErrors(): boolean; end(emitError: boolean): NodeJS.ReadWriteStream; } export function createReporter(): IReporter { - const errors: Error[] = []; + const errors: string[] = []; allErrors.push(errors); class ReportFunc { - constructor(err: Error) { + constructor(err: string) { errors.push(err); } @@ -97,4 +104,4 @@ export function createReporter(): IReporter { } return ReportFunc; -}; +} diff --git a/build/lib/test/util.test.js b/build/lib/test/util.test.js new file mode 100644 index 00000000000..ef0616173b6 --- /dev/null +++ b/build/lib/test/util.test.js @@ -0,0 +1,56 @@ +"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 }); +var assert = require("assert"); +var util = require("../util"); +function getMockTagExists(tags) { + return function (tag) { return tags.indexOf(tag) >= 0; }; +} +suite('util tests', function () { + test('getPreviousVersion - patch', function () { + assert.equal(util.getPreviousVersion('1.2.3', getMockTagExists(['1.2.2', '1.2.1', '1.2.0', '1.1.0'])), '1.2.2'); + }); + test('getPreviousVersion - patch invalid', function () { + try { + util.getPreviousVersion('1.2.2', getMockTagExists(['1.2.0', '1.1.0'])); + } + catch (e) { + // expected + return; + } + throw new Error('Expected an exception'); + }); + test('getPreviousVersion - minor', function () { + assert.equal(util.getPreviousVersion('1.2.0', getMockTagExists(['1.1.0', '1.1.1', '1.1.2', '1.1.3'])), '1.1.3'); + assert.equal(util.getPreviousVersion('1.2.0', getMockTagExists(['1.1.0', '1.0.0'])), '1.1.0'); + }); + test('getPreviousVersion - minor gap', function () { + assert.equal(util.getPreviousVersion('1.2.0', getMockTagExists(['1.1.0', '1.1.1', '1.1.3'])), '1.1.1'); + }); + test('getPreviousVersion - minor invalid', function () { + try { + util.getPreviousVersion('1.2.0', getMockTagExists(['1.0.0'])); + } + catch (e) { + // expected + return; + } + throw new Error('Expected an exception'); + }); + test('getPreviousVersion - major', function () { + assert.equal(util.getPreviousVersion('2.0.0', getMockTagExists(['1.0.0', '1.1.0', '1.2.0', '1.2.1', '1.2.2'])), '1.2.2'); + }); + test('getPreviousVersion - major invalid', function () { + try { + util.getPreviousVersion('3.0.0', getMockTagExists(['1.0.0'])); + } + catch (e) { + // expected + return; + } + throw new Error('Expected an exception'); + }); +}); diff --git a/build/lib/test/util.test.ts b/build/lib/test/util.test.ts new file mode 100644 index 00000000000..928e730f06c --- /dev/null +++ b/build/lib/test/util.test.ts @@ -0,0 +1,79 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert = require('assert'); +import util = require('../util'); + +function getMockTagExists(tags: string[]) { + return (tag: string) => tags.indexOf(tag) >= 0; +} + +suite('util tests', () => { + test('getPreviousVersion - patch', () => { + assert.equal( + util.getPreviousVersion('1.2.3', getMockTagExists(['1.2.2', '1.2.1', '1.2.0', '1.1.0'])), + '1.2.2' + ); + }); + + test('getPreviousVersion - patch invalid', () => { + try { + util.getPreviousVersion('1.2.2', getMockTagExists(['1.2.0', '1.1.0'])); + } catch (e) { + // expected + return; + } + + throw new Error('Expected an exception'); + }); + + test('getPreviousVersion - minor', () => { + assert.equal( + util.getPreviousVersion('1.2.0', getMockTagExists(['1.1.0', '1.1.1', '1.1.2', '1.1.3'])), + '1.1.3' + ); + + assert.equal( + util.getPreviousVersion('1.2.0', getMockTagExists(['1.1.0', '1.0.0'])), + '1.1.0' + ); + }); + + test('getPreviousVersion - minor gap', () => { + assert.equal( + util.getPreviousVersion('1.2.0', getMockTagExists(['1.1.0', '1.1.1', '1.1.3'])), + '1.1.1' + ); + }); + + test('getPreviousVersion - minor invalid', () => { + try { + util.getPreviousVersion('1.2.0', getMockTagExists(['1.0.0'])); + } catch (e) { + // expected + return; + } + + throw new Error('Expected an exception'); + }); + + test('getPreviousVersion - major', () => { + assert.equal( + util.getPreviousVersion('2.0.0', getMockTagExists(['1.0.0', '1.1.0', '1.2.0', '1.2.1', '1.2.2'])), + '1.2.2' + ); + }); + + test('getPreviousVersion - major invalid', () => { + try { + util.getPreviousVersion('3.0.0', getMockTagExists(['1.0.0'])); + } catch (e) { + // expected + return; + } + + throw new Error('Expected an exception'); + }); +}); diff --git a/build/lib/util.js b/build/lib/util.js index 245ee13ae82..1a2d40327cd 100644 --- a/build/lib/util.js +++ b/build/lib/util.js @@ -14,6 +14,7 @@ var fs = require("fs"); var _rimraf = require("rimraf"); var git = require("./git"); var VinylFile = require("vinyl"); +var cp = require("child_process"); var NoCancellationToken = { isCancellationRequested: function () { return false; } }; function incremental(streamProvider, initial, supportsCancellation) { var input = es.through(); @@ -210,3 +211,68 @@ function filter(fn) { return result; } exports.filter = filter; +function tagExists(tagName) { + try { + cp.execSync("git rev-parse " + tagName, { stdio: 'ignore' }); + return true; + } + catch (e) { + return false; + } +} +/** + * Returns the version previous to the given version. Throws if a git tag for that version doesn't exist. + * Given 1.17.2, return 1.17.1 + * 1.18.0 => 1.17.2. (or the highest 1.17.x) + * 2.0.0 => 1.18.0 (or the highest 1.x) + */ +function getPreviousVersion(versionStr, _tagExists) { + if (_tagExists === void 0) { _tagExists = tagExists; } + function getLatestTagFromBase(semverArr, componentToTest) { + var baseVersion = semverArr.join('.'); + if (!_tagExists(baseVersion)) { + throw new Error('Failed to find git tag for base version, ' + baseVersion); + } + var goodTag; + do { + goodTag = semverArr.join('.'); + semverArr[componentToTest]++; + } while (_tagExists(semverArr.join('.'))); + return goodTag; + } + var semverArr = versionStringToNumberArray(versionStr); + if (semverArr[2] > 0) { + semverArr[2]--; + var previous = semverArr.join('.'); + if (!_tagExists(previous)) { + throw new Error('Failed to find git tag for previous version, ' + previous); + } + return previous; + } + else if (semverArr[1] > 0) { + semverArr[1]--; + return getLatestTagFromBase(semverArr, 2); + } + else { + semverArr[0]--; + // Find 1.x.0 for latest x + var latestMinorVersion = getLatestTagFromBase(semverArr, 1); + // Find 1.x.y for latest y + return getLatestTagFromBase(versionStringToNumberArray(latestMinorVersion), 2); + } +} +exports.getPreviousVersion = getPreviousVersion; +function versionStringToNumberArray(versionStr) { + return versionStr + .split('.') + .map(function (s) { return parseInt(s); }); +} +function versionStringToNumber(versionStr) { + var semverRegex = /(\d+)\.(\d+)\.(\d+)/; + var match = versionStr.match(semverRegex); + if (!match) { + throw new Error('Version string is not properly formatted: ' + versionStr); + } + return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10); +} +exports.versionStringToNumber = versionStringToNumber; diff --git a/build/lib/util.ts b/build/lib/util.ts index bae298f5f05..9dcbbe72484 100644 --- a/build/lib/util.ts +++ b/build/lib/util.ts @@ -17,6 +17,7 @@ import * as git from './git'; import * as VinylFile from 'vinyl'; import { ThroughStream } from 'through'; import * as sm from 'source-map'; +import * as cp from 'child_process'; export interface ICancellationToken { isCancellationRequested(): boolean; @@ -268,4 +269,74 @@ export function filter(fn: (data: any) => boolean): FilterStream { result.restore = es.through(); return result; -} \ No newline at end of file +} + +function tagExists(tagName: string): boolean { + try { + cp.execSync(`git rev-parse ${tagName}`, { stdio: 'ignore' }); + return true; + } catch (e) { + return false; + } +} + +/** + * Returns the version previous to the given version. Throws if a git tag for that version doesn't exist. + * Given 1.17.2, return 1.17.1 + * 1.18.0 => 1.17.2. (or the highest 1.17.x) + * 2.0.0 => 1.18.0 (or the highest 1.x) + */ +export function getPreviousVersion(versionStr: string, _tagExists = tagExists) { + function getLatestTagFromBase(semverArr: number[], componentToTest: number): string { + const baseVersion = semverArr.join('.'); + if (!_tagExists(baseVersion)) { + throw new Error('Failed to find git tag for base version, ' + baseVersion); + } + + let goodTag; + do { + goodTag = semverArr.join('.'); + semverArr[componentToTest]++; + } while (_tagExists(semverArr.join('.'))); + + return goodTag; + } + + const semverArr = versionStringToNumberArray(versionStr); + if (semverArr[2] > 0) { + semverArr[2]--; + const previous = semverArr.join('.'); + if (!_tagExists(previous)) { + throw new Error('Failed to find git tag for previous version, ' + previous); + } + + return previous; + } else if (semverArr[1] > 0) { + semverArr[1]--; + return getLatestTagFromBase(semverArr, 2); + } else { + semverArr[0]--; + + // Find 1.x.0 for latest x + const latestMinorVersion = getLatestTagFromBase(semverArr, 1); + + // Find 1.x.y for latest y + return getLatestTagFromBase(versionStringToNumberArray(latestMinorVersion), 2); + } +} + +function versionStringToNumberArray(versionStr: string): number[] { + return versionStr + .split('.') + .map(s => parseInt(s)); +} + +export function versionStringToNumber(versionStr: string) { + const semverRegex = /(\d+)\.(\d+)\.(\d+)/; + const match = versionStr.match(semverRegex); + if (!match) { + throw new Error('Version string is not properly formatted: ' + versionStr); + } + + return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10); +} diff --git a/build/package.json b/build/package.json index 2d8dc9089f0..ade3af750cb 100644 --- a/build/package.json +++ b/build/package.json @@ -9,12 +9,15 @@ "@types/mime": "0.0.29", "@types/node": "8.0.33", "@types/xml2js": "0.0.33", + "@types/request": "^2.47.0", "azure-storage": "^2.1.0", "documentdb": "1.13.0", "mime": "^1.3.4", "minimist": "^1.2.0", - "typescript": "2.7.2", - "xml2js": "^0.4.17" + "typescript": "2.8.1", + "xml2js": "^0.4.17", + "github-releases": "^0.4.1", + "request": "^2.85.0" }, "scripts": { "compile": "tsc -p tsconfig.build.json", diff --git a/build/tfs/common/symbols.ts b/build/tfs/common/symbols.ts new file mode 100644 index 00000000000..5e4ebbd1a03 --- /dev/null +++ b/build/tfs/common/symbols.ts @@ -0,0 +1,209 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as request from 'request'; +import { createReadStream, createWriteStream, unlink, mkdir } from 'fs'; +import * as github from 'github-releases'; +import { join } from 'path'; +import { tmpdir } from 'os'; +import { promisify } from 'util'; + +const BASE_URL = 'https://rink.hockeyapp.net/api/2/'; +const HOCKEY_APP_TOKEN_HEADER = 'X-HockeyAppToken'; + +export interface IVersions { + app_versions: IVersion[]; +} + +export interface IVersion { + id: number; + version: string; +} + +export interface IApplicationAccessor { + accessToken: string; + appId: string; +} + +export interface IVersionAccessor extends IApplicationAccessor { + id: string; +} + +enum Platform { + WIN_32 = 'win32-ia32', + WIN_64 = 'win32-x64', + LINUX_32 = 'linux-ia32', + LINUX_64 = 'linux-x64', + MAC_OS = 'darwin-x64' +} + +function symbolsZipName(platform: Platform, electronVersion: string, insiders: boolean): string { + return `${insiders ? 'insiders' : 'stable'}-symbols-v${electronVersion}-${platform}.zip`; +} + +const SEED = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +async function tmpFile(name: string): Promise { + let res = ''; + for (let i = 0; i < 8; i++) { + res += SEED.charAt(Math.floor(Math.random() * SEED.length)); + } + + const tmpParent = join(tmpdir(), res); + + await promisify(mkdir)(tmpParent); + + return join(tmpParent, name); +} + +async function getVersions(accessor: IApplicationAccessor): Promise { + return await asyncRequest({ + url: `${BASE_URL}/apps/${accessor.appId}/app_versions`, + method: 'GET', + headers: { + [HOCKEY_APP_TOKEN_HEADER]: accessor.accessToken + } + }); +} + +async function createVersion(accessor: IApplicationAccessor, version: string): Promise { + return await asyncRequest({ + url: `${BASE_URL}/apps/${accessor.appId}/app_versions/new`, + method: 'POST', + headers: { + [HOCKEY_APP_TOKEN_HEADER]: accessor.accessToken + }, + formData: { + bundle_version: version + } + }); +} + +async function updateVersion(accessor: IVersionAccessor, symbolsPath: string) { + return await asyncRequest({ + url: `${BASE_URL}/apps/${accessor.appId}/app_versions/${accessor.id}`, + method: 'PUT', + headers: { + [HOCKEY_APP_TOKEN_HEADER]: accessor.accessToken + }, + formData: { + dsym: createReadStream(symbolsPath) + } + }); +} + +async function asyncRequest(options: request.UrlOptions & request.CoreOptions): Promise { + return new Promise((resolve, reject) => { + request(options, (error, response, body) => { + if (error) { + reject(error); + } else { + resolve(JSON.parse(body)); + } + }); + }); +} + +async function downloadAsset(repository, assetName: string, targetPath: string, electronVersion: string) { + return new Promise((resolve, reject) => { + repository.getReleases({ tag_name: `v${electronVersion}` }, (err, releases) => { + if (err) { + reject(err); + } else { + const asset = releases[0].assets.filter(asset => asset.name === assetName)[0]; + if (!asset) { + reject(new Error(`Asset with name ${assetName} not found`)); + } else { + repository.downloadAsset(asset, (err, reader) => { + if (err) { + reject(err); + } else { + const writer = createWriteStream(targetPath); + writer.on('error', reject); + writer.on('close', resolve); + reader.on('error', reject); + + reader.pipe(writer); + } + }); + } + } + }); + }); +} + +interface IOptions { + platform: Platform; + versions: { code: string; insiders: boolean; electron: string; }; + access: { hockeyAppToken: string; hockeyAppId: string; githubToken: string }; +} + +async function ensureVersionAndSymbols(options: IOptions) { + + // Check version does not exist + console.log(`HockeyApp: checking for existing version ${options.versions.code} (${options.platform})`); + const versions = await getVersions({ accessToken: options.access.hockeyAppToken, appId: options.access.hockeyAppId }); + if (versions.app_versions.some(v => v.version === options.versions.code)) { + console.log(`Returning without uploading symbols because version ${options.versions.code} (${options.platform}) was already found`); + return; + } + + // Download symbols for platform and electron version + const symbolsName = symbolsZipName(options.platform, options.versions.electron, options.versions.insiders); + const symbolsPath = await tmpFile('symbols.zip'); + console.log(`HockeyApp: downloading symbols ${symbolsName} for electron ${options.versions.electron} (${options.platform}) into ${symbolsPath}`); + await downloadAsset(new github({ repo: 'Microsoft/vscode-electron-prebuilt', token: options.access.githubToken }), symbolsName, symbolsPath, options.versions.electron); + + // Create version + console.log(`HockeyApp: creating new version ${options.versions.code} (${options.platform})`); + const version = await createVersion({ accessToken: options.access.hockeyAppToken, appId: options.access.hockeyAppId }, options.versions.code); + + // Upload symbols + console.log(`HockeyApp: uploading symbols for version ${options.versions.code} (${options.platform})`); + await updateVersion({ id: String(version.id), accessToken: options.access.hockeyAppToken, appId: options.access.hockeyAppId }, symbolsPath); + + // Cleanup + await promisify(unlink)(symbolsPath); +} + +// Environment +const pakage = require('../../../package.json'); +const product = require('../../../product.json'); +const codeVersion = pakage.version; +const electronVersion = require('../../lib/electron').getElectronVersion(); +const insiders = product.quality !== 'stable'; +const githubToken = process.argv[2]; +const hockeyAppToken = process.argv[3]; +const is64 = process.argv[4] === 'x64'; +const hockeyAppId = process.argv[5]; + +let platform: Platform; +if (process.platform === 'darwin') { + platform = Platform.MAC_OS; +} else if (process.platform === 'win32') { + platform = is64 ? Platform.WIN_64 : Platform.WIN_32; +} else { + platform = is64 ? Platform.LINUX_64 : Platform.LINUX_32; +} + +// Create version and upload symbols in HockeyApp +ensureVersionAndSymbols({ + platform, + versions: { + code: codeVersion, + insiders, + electron: electronVersion + }, + access: { + githubToken, + hockeyAppToken, + hockeyAppId + } +}).then(() => { + console.log('HockeyApp: done'); +}, error => { + console.error(`HockeyApp: error (${error})`); +}); \ No newline at end of file diff --git a/build/tfs/product-build.yml b/build/tfs/product-build.yml index f0e6f2811a3..3b67df7dcf4 100644 --- a/build/tfs/product-build.yml +++ b/build/tfs/product-build.yml @@ -222,6 +222,10 @@ phases: node build/tfs/common/publish.js $Quality "$global:assetPlatform-archive" archive "VSCode-win32-$(VSCODE_ARCH)-$Version.zip" $Version true $Zip node build/tfs/common/publish.js $Quality "$global:assetPlatform" setup "VSCodeSetup-$(VSCODE_ARCH)-$Version.exe" $Version true $Exe + # publish hockeyapp symbols + $hockeyAppId = if ("$(VSCODE_ARCH)" -eq "ia32") { "$(VSCODE_HOCKEYAPP_ID_WIN32)" } else { "$(VSCODE_HOCKEYAPP_ID_WIN64)" } + node build/tfs/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" $hockeyAppId + - phase: Linux condition: eq(variables['VSCODE_BUILD_LINUX'], 'true') queue: linux-x64 @@ -269,6 +273,9 @@ phases: MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \ ./build/tfs/linux/release2.sh "$(VSCODE_ARCH)" "$(LINUX_REPO_PASSWORD)" + # publish hockeyapp symbols + node build/tfs/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_LINUX64)" + - phase: Linux32 condition: eq(variables['VSCODE_BUILD_LINUX'], 'true') queue: linux-ia32 @@ -316,6 +323,9 @@ phases: MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \ ./build/tfs/linux/release2.sh "$(VSCODE_ARCH)" "$(LINUX_REPO_PASSWORD)" + # publish hockeyapp symbols + node build/tfs/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_LINUX32)" + - phase: macOS condition: eq(variables['VSCODE_BUILD_MACOS'], 'true') queue: Hosted macOS Preview @@ -365,6 +375,9 @@ phases: false \ ../VSCode-darwin-unsigned.zip + # publish hockeyapp symbols + node build/tfs/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_MACOS)" + # enqueue the unsigned build AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \ AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \ diff --git a/build/yarn.lock b/build/yarn.lock index ec3bd73e853..59bb057c34d 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -8,6 +8,10 @@ dependencies: "@types/node" "*" +"@types/caseless@*": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.1.tgz#9794c69c8385d0192acc471a540d1f8e0d16218a" + "@types/documentdb@1.10.2": version "1.10.2" resolved "https://registry.yarnpkg.com/@types/documentdb/-/documentdb-1.10.2.tgz#6795025cdc51577af5ed531b6f03bd44404f5350" @@ -22,6 +26,12 @@ version "0.0.33" resolved "https://registry.yarnpkg.com/@types/es6-promise/-/es6-promise-0.0.33.tgz#280a707e62b1b6bef1a86cc0861ec63cd06c7ff3" +"@types/form-data@*": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" + dependencies: + "@types/node" "*" + "@types/mime@0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-0.0.29.tgz#fbcfd330573b912ef59eeee14602bface630754b" @@ -34,6 +44,19 @@ version "8.0.33" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd" +"@types/request@^2.47.0": + version "2.47.0" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.47.0.tgz#76a666cee4cb85dcffea6cd4645227926d9e114e" + dependencies: + "@types/caseless" "*" + "@types/form-data" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + +"@types/tough-cookie@*": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.2.tgz#e0d481d8bb282ad8a8c9e100ceb72c995fb5e709" + "@types/xml2js@0.0.33": version "0.0.33" resolved "https://registry.yarnpkg.com/@types/xml2js/-/xml2js-0.0.33.tgz#20c5dd6460245284d64a55690015b95e409fb7de" @@ -45,6 +68,15 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -65,10 +97,18 @@ aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +aws4@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" + azure-storage@^2.1.0: version "2.6.0" resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-2.6.0.tgz#84747ee54a4bd194bb960f89f3eff89d67acf1cf" @@ -85,6 +125,10 @@ azure-storage@^2.1.0: xml2js "0.2.7" xmlbuilder "0.4.3" +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" @@ -101,6 +145,25 @@ boom@2.x.x: dependencies: hoek "2.x.x" +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + browserify-mime@~1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/browserify-mime/-/browserify-mime-1.2.9.tgz#aeb1af28de6c0d7a6a2ce40adb68ff18422af31f" @@ -113,12 +176,26 @@ co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" +colors@^1.1.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794" + +combined-stream@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" dependencies: delayed-stream "~1.0.0" +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + core-util-is@1.0.2, 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" @@ -129,6 +206,12 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -158,7 +241,7 @@ extend@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/extend/-/extend-1.2.1.tgz#a0f5fd6cfc83a5fe49ef698d60ec8a624dd4576c" -extend@~3.0.0: +extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -166,6 +249,14 @@ extsprintf@1.3.0, extsprintf@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -178,16 +269,37 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" +form-data@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" dependencies: assert-plus "^1.0.0" +github-releases@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/github-releases/-/github-releases-0.4.1.tgz#4a13bdf85c4161344271db3d81db08e7379102ff" + dependencies: + minimatch "3.0.4" + optimist "0.6.1" + prettyjson "1.2.1" + request "2.81.0" + har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + har-validator@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" @@ -195,6 +307,13 @@ har-validator@~4.2.1: ajv "^4.9.1" har-schema "^1.0.5" +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + hash-base@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" @@ -211,10 +330,23 @@ hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" +hoek@4.x.x: + version "4.2.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -223,6 +355,14 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + inherits@^2.0.1, inherits@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -249,6 +389,10 @@ json-edm-parser@0.1.2: dependencies: jsonparse "~1.2.0" +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -291,28 +435,66 @@ mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + mime-types@^2.1.12, mime-types@~2.1.7: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" dependencies: mime-db "~1.30.0" +mime-types@~2.1.17: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + dependencies: + mime-db "~1.33.0" + mime@^1.3.4: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -oauth-sign@~0.8.1: +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" +optimist@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +prettyjson@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prettyjson/-/prettyjson-1.2.1.tgz#fcffab41d19cab4dfae5e575e64246619b12d289" + dependencies: + colors "^1.1.2" + minimist "^1.2.0" + priorityqueuejs@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz#2ee4f23c2560913e08c07ce5ccdd6de3df2c5af8" @@ -329,6 +511,10 @@ qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + readable-stream@~2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -340,7 +526,7 @@ readable-stream@~2.0.0: string_decoder "~0.10.x" util-deprecate "~1.0.1" -request@~2.81.0: +request@2.81.0, request@~2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -367,7 +553,34 @@ request@~2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -safe-buffer@^5.0.1: +request@^2.85.0: + version "2.85.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -389,6 +602,12 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + dependencies: + hoek "4.x.x" + sshpk@^1.7.0: version "1.13.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" @@ -407,7 +626,7 @@ string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" -stringstream@~0.0.4: +stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -417,6 +636,12 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -427,9 +652,9 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" -typescript@2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" +typescript@2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624" underscore@1.8.3, underscore@~1.8.3: version "1.8.3" @@ -443,6 +668,10 @@ uuid@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" +uuid@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + validator@~3.35.0: version "3.35.0" resolved "https://registry.yarnpkg.com/validator/-/validator-3.35.0.tgz#3f07249402c1fc8fc093c32c6e43d72a79cca1dc" @@ -455,6 +684,10 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + xml2js@0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.2.7.tgz#1838518bb01741cae0878bab4915e494c32306af" diff --git a/extensions/emmet/src/test/abbreviationAction.test.ts b/extensions/emmet/src/test/abbreviationAction.test.ts index cf4ba401a23..3c85a027155 100644 --- a/extensions/emmet/src/test/abbreviationAction.test.ts +++ b/extensions/emmet/src/test/abbreviationAction.test.ts @@ -304,6 +304,18 @@ suite('Tests for jsx, xml and xsl', () => { }); }); + test('Expand abbreviation with single quotes for jsx', () => { + return workspace.getConfiguration('emmet').update('syntaxProfiles', {jsx: {"attr_quotes": "single"}}).then(() => { + return withRandomFileEditor('img', 'javascriptreact', (editor, doc) => { + editor.selection = new Selection(0, 6, 0, 6); + return expandEmmetAbbreviation({ language: 'javascriptreact' }).then(() => { + assert.equal(editor.document.getText(), '\'\'/'); + return workspace.getConfiguration('emmet').update('syntaxProfiles', {}); + }); + }); + }); + }); + test('Expand abbreviation with self closing tags for xml', () => { return withRandomFileEditor('img', 'xml', (editor, doc) => { editor.selection = new Selection(0, 6, 0, 6); diff --git a/extensions/emmet/src/test/tagActions.test.ts b/extensions/emmet/src/test/tagActions.test.ts index db664524eb1..ed69ae7d11c 100644 --- a/extensions/emmet/src/test/tagActions.test.ts +++ b/extensions/emmet/src/test/tagActions.test.ts @@ -125,7 +125,7 @@ suite('Tests for Emmet actions on html tags', () => { return splitJoinTag()!.then(() => { assert.equal(doc.getText(), expectedContents); - return Promise.resolve() + return workspace.getConfiguration('emmet').update('syntaxProfiles', {}); }); }); }); diff --git a/extensions/emmet/src/util.ts b/extensions/emmet/src/util.ts index 309be6de79a..3d0d8e2ac5d 100644 --- a/extensions/emmet/src/util.ts +++ b/extensions/emmet/src/util.ts @@ -468,7 +468,10 @@ export function getEmmetConfiguration(syntax: string) { && !syntaxProfiles[syntax].hasOwnProperty('self_closing_tag') // Old Emmet format && !syntaxProfiles[syntax].hasOwnProperty('selfClosingStyle') // Emmet 2.0 format ) { - syntaxProfiles[syntax]['selfClosingStyle'] = 'xml'; + syntaxProfiles[syntax] = { + ...syntaxProfiles[syntax], + selfClosingStyle: 'xml' + }; } } diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index bee53b77de4..d425b739890 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/24b8d8d8b7e31fbec7390f3ed4a9831a6a5c4ca1", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/5c237f767c5cff27910946a3ba65261cc3b6f4bf", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -174,6 +174,9 @@ { "include": "#arrow-function" }, + { + "include": "#paren-expression-possibly-arrow" + }, { "include": "#cast" }, @@ -288,7 +291,7 @@ "patterns": [ { "name": "meta.var-single-variable.expr.js", - "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "beginCaptures": { "1": { "name": "meta.definition.variable.js entity.name.function.js" @@ -522,7 +525,7 @@ } }, { - "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "storage.modifier.js" @@ -748,7 +751,7 @@ "include": "#comment" }, { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "meta.definition.property.js entity.name.function.js" @@ -1033,7 +1036,7 @@ }, { "name": "meta.arrow.js", - "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", + "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", "beginCaptures": { "1": { "name": "storage.modifier.async.js" @@ -1156,6 +1159,13 @@ "name": "punctuation.definition.parameters.end.js" } }, + "patterns": [ + { + "include": "#function-parameters-body" + } + ] + }, + "function-parameters-body": { "patterns": [ { "include": "#comment" @@ -1495,7 +1505,7 @@ "name": "storage.type.namespace.js" } }, - "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1529,7 +1539,7 @@ "name": "entity.name.type.alias.js" } }, - "end": "(?=[};]|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=\\}|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1705,7 +1715,7 @@ "name": "keyword.control.default.js" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#expression" @@ -1720,7 +1730,7 @@ "name": "keyword.control.export.js" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#import-export-declaration" @@ -2039,7 +2049,7 @@ }, { "name": "meta.object.member.js", - "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "0": { "name": "meta.object-literal.key.js" @@ -2119,9 +2129,9 @@ "name": "keyword.operator.ternary.js" } }, - "end": "(:)", + "end": "\\s*(:)", "endCaptures": { - "0": { + "1": { "name": "keyword.operator.ternary.js" } }, @@ -2185,7 +2195,7 @@ "name": "keyword.operator.new.js" } }, - "end": "(?<=\\))|(?=[;),}\\]:]|$|((?)\\s*(async)?(?=\\s*(<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)\\(\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.js" + } + }, + "end": "(?<=\\))", + "patterns": [ + { + "include": "#type-parameters" + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "meta.brace.round.js" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.js" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + { + "begin": "(?<=[(=,]|=>)\\s*(async)?\\s*(\\()(?=\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.js" + }, + "2": { + "name": "meta.brace.round.js" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.js" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + "include": "#possibly-arrow-return-type" + } + ] + }, + "expression-inside-possibly-arrow-parens": { + "patterns": [ + { + "include": "#expressionWithoutIdentifiers" + }, + { + "include": "#function-parameters-body" + }, + { + "include": "#identifiers" + }, + { + "include": "#expressionPunctuations" + } + ] + }, "paren-expression": { "begin": "\\(", "beginCaptures": { @@ -2228,9 +2316,6 @@ "patterns": [ { "include": "#expression" - }, - { - "include": "#punctuation-comma" } ] }, @@ -2713,7 +2798,7 @@ "include": "#object-identifiers" }, { - "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", + "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", "captures": { "1": { "name": "punctuation.accessor.js" @@ -2899,6 +2984,28 @@ } }, "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "possibly-arrow-return-type": { + "begin": "(?<=\\))\\s*(:)(?=\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+\\s*=>)", + "beginCaptures": { + "1": { + "name": "meta.arrow.js meta.return.type.arrow.js keyword.operator.type.annotation.js" + } + }, + "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "contentName": "meta.arrow.js meta.return.type.arrow.js", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "arrow-return-type-body": { "patterns": [ { "begin": "(?<=[:])(?=\\s*\\{)", diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 035c6167a75..1501020eeb4 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/24b8d8d8b7e31fbec7390f3ed4a9831a6a5c4ca1", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/5c237f767c5cff27910946a3ba65261cc3b6f4bf", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -174,6 +174,9 @@ { "include": "#arrow-function" }, + { + "include": "#paren-expression-possibly-arrow" + }, { "include": "#cast" }, @@ -288,7 +291,7 @@ "patterns": [ { "name": "meta.var-single-variable.expr.js.jsx", - "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "beginCaptures": { "1": { "name": "meta.definition.variable.js.jsx entity.name.function.js.jsx" @@ -522,7 +525,7 @@ } }, { - "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "storage.modifier.js.jsx" @@ -748,7 +751,7 @@ "include": "#comment" }, { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "meta.definition.property.js.jsx entity.name.function.js.jsx" @@ -1033,7 +1036,7 @@ }, { "name": "meta.arrow.js.jsx", - "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", + "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", "beginCaptures": { "1": { "name": "storage.modifier.async.js.jsx" @@ -1156,6 +1159,13 @@ "name": "punctuation.definition.parameters.end.js.jsx" } }, + "patterns": [ + { + "include": "#function-parameters-body" + } + ] + }, + "function-parameters-body": { "patterns": [ { "include": "#comment" @@ -1495,7 +1505,7 @@ "name": "storage.type.namespace.js.jsx" } }, - "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1529,7 +1539,7 @@ "name": "entity.name.type.alias.js.jsx" } }, - "end": "(?=[};]|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=\\}|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1705,7 +1715,7 @@ "name": "keyword.control.default.js.jsx" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#expression" @@ -1720,7 +1730,7 @@ "name": "keyword.control.export.js.jsx" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#import-export-declaration" @@ -2039,7 +2049,7 @@ }, { "name": "meta.object.member.js.jsx", - "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "0": { "name": "meta.object-literal.key.js.jsx" @@ -2119,9 +2129,9 @@ "name": "keyword.operator.ternary.js.jsx" } }, - "end": "(:)", + "end": "\\s*(:)", "endCaptures": { - "0": { + "1": { "name": "keyword.operator.ternary.js.jsx" } }, @@ -2185,7 +2195,7 @@ "name": "keyword.operator.new.js.jsx" } }, - "end": "(?<=\\))|(?=[;),}\\]:]|$|((?)\\s*(async)?(?=\\s*(<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)\\(\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.js.jsx" + } + }, + "end": "(?<=\\))", + "patterns": [ + { + "include": "#type-parameters" + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "meta.brace.round.js.jsx" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.js.jsx" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + { + "begin": "(?<=[(=,]|=>)\\s*(async)?\\s*(\\()(?=\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.js.jsx" + }, + "2": { + "name": "meta.brace.round.js.jsx" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.js.jsx" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + "include": "#possibly-arrow-return-type" + } + ] + }, + "expression-inside-possibly-arrow-parens": { + "patterns": [ + { + "include": "#expressionWithoutIdentifiers" + }, + { + "include": "#function-parameters-body" + }, + { + "include": "#identifiers" + }, + { + "include": "#expressionPunctuations" + } + ] + }, "paren-expression": { "begin": "\\(", "beginCaptures": { @@ -2228,9 +2316,6 @@ "patterns": [ { "include": "#expression" - }, - { - "include": "#punctuation-comma" } ] }, @@ -2713,7 +2798,7 @@ "include": "#object-identifiers" }, { - "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", + "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", "captures": { "1": { "name": "punctuation.accessor.js.jsx" @@ -2899,6 +2984,28 @@ } }, "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "possibly-arrow-return-type": { + "begin": "(?<=\\))\\s*(:)(?=\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+\\s*=>)", + "beginCaptures": { + "1": { + "name": "meta.arrow.js.jsx meta.return.type.arrow.js.jsx keyword.operator.type.annotation.js.jsx" + } + }, + "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "contentName": "meta.arrow.js.jsx meta.return.type.arrow.js.jsx", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "arrow-return-type-body": { "patterns": [ { "begin": "(?<=[:])(?=\\s*\\{)", diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 4209215a5f8..6b1a0d56b95 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/6e1063a71d4d017f976ccbe3d68138f4662c9a66", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/641c88a57c3f33ef8bcb504202f8330acef39b9e", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -1668,14 +1668,103 @@ "name": "markup.fenced_code.block.markdown" }, "heading": { - "begin": "(?:^|\\G)[ ]{0,3}(#{1,6})\\s*(?=[\\S[^#]])", + "match": "(?:^|\\G)[ ]{0,3}((#{1,6})\\s*(?=[\\S[^#]]).*?\\s*(#{1,6})?)$\\n?", "captures": { "1": { - "name": "punctuation.definition.heading.markdown" + "patterns": [ + { + "match": "(#{6})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "name": "heading.6.markdown", + "captures": { + "1": { + "name": "punctuation.definition.heading.markdown" + }, + "2": { + "name": "entity.name.section.markdown" + }, + "3": { + "name": "punctuation.definition.heading.markdown" + } + } + }, + { + "match": "(#{5})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "name": "heading.5.markdown", + "captures": { + "1": { + "name": "punctuation.definition.heading.markdown" + }, + "2": { + "name": "entity.name.section.markdown" + }, + "3": { + "name": "punctuation.definition.heading.markdown" + } + } + }, + { + "match": "(#{4})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "name": "heading.4.markdown", + "captures": { + "1": { + "name": "punctuation.definition.heading.markdown" + }, + "2": { + "name": "entity.name.section.markdown" + }, + "3": { + "name": "punctuation.definition.heading.markdown" + } + } + }, + { + "match": "(#{3})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "name": "heading.3.markdown", + "captures": { + "1": { + "name": "punctuation.definition.heading.markdown" + }, + "2": { + "name": "entity.name.section.markdown" + }, + "3": { + "name": "punctuation.definition.heading.markdown" + } + } + }, + { + "match": "(#{2})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "name": "heading.2.markdown", + "captures": { + "1": { + "name": "punctuation.definition.heading.markdown" + }, + "2": { + "name": "entity.name.section.markdown" + }, + "3": { + "name": "punctuation.definition.heading.markdown" + } + } + }, + { + "match": "(#{1})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "name": "heading.1.markdown", + "captures": { + "1": { + "name": "punctuation.definition.heading.markdown" + }, + "2": { + "name": "entity.name.section.markdown" + }, + "3": { + "name": "punctuation.definition.heading.markdown" + } + } + } + ] } }, - "contentName": "entity.name.section.markdown", - "end": "\\s*(#{1,6})?$\\n?", "name": "markup.heading.markdown", "patterns": [ { diff --git a/extensions/markdown-basics/test/colorize-results/test-33886_md.json b/extensions/markdown-basics/test/colorize-results/test-33886_md.json index ed8d6a43aaa..185d172e8af 100644 --- a/extensions/markdown-basics/test/colorize-results/test-33886_md.json +++ b/extensions/markdown-basics/test/colorize-results/test-33886_md.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -12,7 +12,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -23,7 +23,7 @@ }, { "c": "h", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -177,7 +177,7 @@ }, { "c": "#", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -188,7 +188,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -199,7 +199,7 @@ }, { "c": "h", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -298,7 +298,7 @@ }, { "c": "#", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -309,7 +309,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -320,7 +320,7 @@ }, { "c": "h", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", diff --git a/extensions/markdown-basics/test/colorize-results/test_md.json b/extensions/markdown-basics/test/colorize-results/test_md.json index a3dd8829dfe..eb09a71c815 100644 --- a/extensions/markdown-basics/test/colorize-results/test_md.json +++ b/extensions/markdown-basics/test/colorize-results/test_md.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -12,7 +12,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -23,7 +23,7 @@ }, { "c": "Header 1", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -33,19 +33,8 @@ } }, { - "c": " ", - "t": "text.html.markdown markup.heading.markdown", - "r": { - "dark_plus": "markup.heading: #569CD6", - "light_plus": "markup.heading: #800000", - "dark_vs": "markup.heading: #569CD6", - "light_vs": "markup.heading: #800000", - "hc_black": "markup.heading: #6796E6" - } - }, - { - "c": "#", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "c": " #", + "t": "text.html.markdown markup.heading.markdown heading.1.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -56,7 +45,7 @@ }, { "c": "##", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -67,7 +56,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -78,7 +67,7 @@ }, { "c": "Header 2", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -88,19 +77,8 @@ } }, { - "c": " ", - "t": "text.html.markdown markup.heading.markdown", - "r": { - "dark_plus": "markup.heading: #569CD6", - "light_plus": "markup.heading: #800000", - "dark_vs": "markup.heading: #569CD6", - "light_vs": "markup.heading: #800000", - "hc_black": "markup.heading: #6796E6" - } - }, - { - "c": "##", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "c": " ##", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -111,7 +89,7 @@ }, { "c": "###", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -122,7 +100,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -133,7 +111,7 @@ }, { "c": "Header 3 ### (Hashes on right are optional)", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -144,7 +122,7 @@ }, { "c": "##", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -155,7 +133,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -166,7 +144,7 @@ }, { "c": "Markdown plus h2 with a custom ID ## {#id-goes-here}", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -243,7 +221,7 @@ }, { "c": "###", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -254,7 +232,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -265,7 +243,7 @@ }, { "c": "Alternate heading styles:", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2025,7 +2003,7 @@ }, { "c": "###", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2036,7 +2014,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2047,7 +2025,7 @@ }, { "c": "Horizontal rules", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.3.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2201,7 +2179,7 @@ }, { "c": "##", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2212,7 +2190,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2223,7 +2201,7 @@ }, { "c": "Markdown plus tables", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2233,19 +2211,8 @@ } }, { - "c": " ", - "t": "text.html.markdown markup.heading.markdown", - "r": { - "dark_plus": "markup.heading: #569CD6", - "light_plus": "markup.heading: #800000", - "dark_vs": "markup.heading: #569CD6", - "light_vs": "markup.heading: #800000", - "hc_black": "markup.heading: #6796E6" - } - }, - { - "c": "##", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "c": " ##", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2366,7 +2333,7 @@ }, { "c": "##", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2377,7 +2344,7 @@ }, { "c": " ", - "t": "text.html.markdown markup.heading.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2388,7 +2355,7 @@ }, { "c": "Markdown plus definition lists", - "t": "text.html.markdown markup.heading.markdown entity.name.section.markdown", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown entity.name.section.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", @@ -2398,19 +2365,8 @@ } }, { - "c": " ", - "t": "text.html.markdown markup.heading.markdown", - "r": { - "dark_plus": "markup.heading: #569CD6", - "light_plus": "markup.heading: #800000", - "dark_vs": "markup.heading: #569CD6", - "light_vs": "markup.heading: #800000", - "hc_black": "markup.heading: #6796E6" - } - }, - { - "c": "##", - "t": "text.html.markdown markup.heading.markdown punctuation.definition.heading.markdown", + "c": " ##", + "t": "text.html.markdown markup.heading.markdown heading.2.markdown punctuation.definition.heading.markdown", "r": { "dark_plus": "markup.heading: #569CD6", "light_plus": "markup.heading: #800000", diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 37a21b493fa..bdf8134fc73 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -155,7 +155,7 @@ export class MarkdownPreview { private readonly _onDisposeEmitter = new vscode.EventEmitter(); public readonly onDispose = this._onDisposeEmitter.event; - private readonly _onDidChangeViewStateEmitter = new vscode.EventEmitter(); + private readonly _onDidChangeViewStateEmitter = new vscode.EventEmitter(); public readonly onDidChangeViewState = this._onDidChangeViewStateEmitter.event; public get resource(): vscode.Uri { diff --git a/extensions/markdown-language-features/src/tableOfContentsProvider.ts b/extensions/markdown-language-features/src/tableOfContentsProvider.ts index 1211e731e82..cca46aae81a 100644 --- a/extensions/markdown-language-features/src/tableOfContentsProvider.ts +++ b/extensions/markdown-language-features/src/tableOfContentsProvider.ts @@ -8,7 +8,7 @@ import * as vscode from 'vscode'; import { MarkdownEngine } from './markdownEngine'; export class Slug { - private static specialChars: any = { 'à': 'a', 'ä': 'a', 'ã': 'a', 'á': 'a', 'â': 'a', 'æ': 'a', 'å': 'a', 'ë': 'e', 'è': 'e', 'é': 'e', 'ê': 'e', 'î': 'i', 'ï': 'i', 'ì': 'i', 'í': 'i', 'ò': 'o', 'ó': 'o', 'ö': 'o', 'ô': 'o', 'ø': 'o', 'ù': 'o', 'ú': 'u', 'ü': 'u', 'û': 'u', 'ñ': 'n', 'ç': 'c', 'ß': 's', 'ÿ': 'y', 'œ': 'o', 'ŕ': 'r', 'ś': 's', 'ń': 'n', 'ṕ': 'p', 'ẃ': 'w', 'ǵ': 'g', 'ǹ': 'n', 'ḿ': 'm', 'ǘ': 'u', 'ẍ': 'x', 'ź': 'z', 'ḧ': 'h', '·': '-', '/': '-', '_': '-', ',': '-', ':': '-', ';': '-' }; + private static specialChars: any = { 'à': 'a', 'ä': 'a', 'ã': 'a', 'á': 'a', 'â': 'a', 'æ': 'a', 'å': 'a', 'ë': 'e', 'è': 'e', 'é': 'e', 'ê': 'e', 'î': 'i', 'ï': 'i', 'ì': 'i', 'í': 'i', 'ò': 'o', 'ó': 'o', 'ö': 'o', 'ô': 'o', 'ø': 'o', 'ù': 'o', 'ú': 'u', 'ü': 'u', 'û': 'u', 'ñ': 'n', 'ç': 'c', 'ß': 's', 'ÿ': 'y', 'œ': 'o', 'ŕ': 'r', 'ś': 's', 'ń': 'n', 'ṕ': 'p', 'ẃ': 'w', 'ǵ': 'g', 'ǹ': 'n', 'ḿ': 'm', 'ǘ': 'u', 'ẍ': 'x', 'ź': 'z', 'ḧ': 'h', '·': '-', '/': '-', '_': '-', ',': '-', ':': '-', ';': '-', 'З': '3', 'з': '3' }; public static fromHeading(heading: string): Slug { const slugifiedHeading = encodeURI(heading.trim() diff --git a/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts b/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts index 0a2b2350f58..df6fb0558cc 100644 --- a/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts +++ b/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts @@ -82,6 +82,14 @@ suite('markdown.TableOfContentsProvider', () => { assert.strictEqual((await provider.lookup('indentacao'))!.line, 0); }); + + test('should map special З, #37079', async () => { + const doc = new InMemoryDocument(testFileName, `### Заголовок Header 3`); + const provider = new TableOfContentsProvider(newEngine(), doc); + + assert.strictEqual((await provider.lookup('Заголовок-header-3'))!.line, 0); + assert.strictEqual((await provider.lookup('3аголовок-header-3'))!.line, 0); + }); }); function newEngine(): MarkdownEngine { diff --git a/extensions/package.json b/extensions/package.json index efc4da072e5..b0072fb9737 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "2.8.1" + "typescript": "2.8.3-insiders.20180407" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json index 63d19b71264..10e0aacba78 100644 --- a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/24b8d8d8b7e31fbec7390f3ed4a9831a6a5c4ca1", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/5c237f767c5cff27910946a3ba65261cc3b6f4bf", "name": "TypeScript", "scopeName": "source.ts", "patterns": [ @@ -171,6 +171,9 @@ { "include": "#arrow-function" }, + { + "include": "#paren-expression-possibly-arrow" + }, { "include": "#cast" }, @@ -285,7 +288,7 @@ "patterns": [ { "name": "meta.var-single-variable.expr.ts", - "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "beginCaptures": { "1": { "name": "meta.definition.variable.ts entity.name.function.ts" @@ -519,7 +522,7 @@ } }, { - "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "storage.modifier.ts" @@ -745,7 +748,7 @@ "include": "#comment" }, { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "meta.definition.property.ts entity.name.function.ts" @@ -1030,7 +1033,7 @@ }, { "name": "meta.arrow.ts", - "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", + "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", "beginCaptures": { "1": { "name": "storage.modifier.async.ts" @@ -1153,6 +1156,13 @@ "name": "punctuation.definition.parameters.end.ts" } }, + "patterns": [ + { + "include": "#function-parameters-body" + } + ] + }, + "function-parameters-body": { "patterns": [ { "include": "#comment" @@ -1492,7 +1502,7 @@ "name": "storage.type.namespace.ts" } }, - "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1526,7 +1536,7 @@ "name": "entity.name.type.alias.ts" } }, - "end": "(?=[};]|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=\\}|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1702,7 +1712,7 @@ "name": "keyword.control.default.ts" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#expression" @@ -1717,7 +1727,7 @@ "name": "keyword.control.export.ts" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#import-export-declaration" @@ -2036,7 +2046,7 @@ }, { "name": "meta.object.member.ts", - "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "0": { "name": "meta.object-literal.key.ts" @@ -2116,9 +2126,9 @@ "name": "keyword.operator.ternary.ts" } }, - "end": "(:)", + "end": "\\s*(:)", "endCaptures": { - "0": { + "1": { "name": "keyword.operator.ternary.ts" } }, @@ -2182,7 +2192,7 @@ "name": "keyword.operator.new.ts" } }, - "end": "(?<=\\))|(?=[;),}\\]:]|$|((?)\\s*(async)?(?=\\s*(<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)\\(\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.ts" + } + }, + "end": "(?<=\\))", + "patterns": [ + { + "include": "#type-parameters" + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "meta.brace.round.ts" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.ts" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + { + "begin": "(?<=[(=,]|=>)\\s*(async)?\\s*(\\()(?=\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.ts" + }, + "2": { + "name": "meta.brace.round.ts" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.ts" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + "include": "#possibly-arrow-return-type" + } + ] + }, + "expression-inside-possibly-arrow-parens": { + "patterns": [ + { + "include": "#expressionWithoutIdentifiers" + }, + { + "include": "#function-parameters-body" + }, + { + "include": "#identifiers" + }, + { + "include": "#expressionPunctuations" + } + ] + }, "paren-expression": { "begin": "\\(", "beginCaptures": { @@ -2225,9 +2313,6 @@ "patterns": [ { "include": "#expression" - }, - { - "include": "#punctuation-comma" } ] }, @@ -2747,7 +2832,7 @@ "include": "#object-identifiers" }, { - "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", + "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?[\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", "captures": { "1": { "name": "punctuation.accessor.ts" @@ -2933,6 +3018,28 @@ } }, "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "possibly-arrow-return-type": { + "begin": "(?<=\\))\\s*(:)(?=\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+\\s*=>)", + "beginCaptures": { + "1": { + "name": "meta.arrow.ts meta.return.type.arrow.ts keyword.operator.type.annotation.ts" + } + }, + "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "contentName": "meta.arrow.ts meta.return.type.arrow.ts", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "arrow-return-type-body": { "patterns": [ { "begin": "(?<=[:])(?=\\s*\\{)", diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index d54948c7c93..97e76452d41 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/24b8d8d8b7e31fbec7390f3ed4a9831a6a5c4ca1", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/5c237f767c5cff27910946a3ba65261cc3b6f4bf", "name": "TypeScriptReact", "scopeName": "source.tsx", "patterns": [ @@ -174,6 +174,9 @@ { "include": "#arrow-function" }, + { + "include": "#paren-expression-possibly-arrow" + }, { "include": "#cast" }, @@ -288,7 +291,7 @@ "patterns": [ { "name": "meta.var-single-variable.expr.tsx", - "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "beginCaptures": { "1": { "name": "meta.definition.variable.tsx entity.name.function.tsx" @@ -522,7 +525,7 @@ } }, { - "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "storage.modifier.tsx" @@ -748,7 +751,7 @@ "include": "#comment" }, { - "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "1": { "name": "meta.definition.property.tsx entity.name.function.tsx" @@ -1033,7 +1036,7 @@ }, { "name": "meta.arrow.tsx", - "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", + "begin": "(?x) (?:\n (? is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n )\n)", "beginCaptures": { "1": { "name": "storage.modifier.async.tsx" @@ -1156,6 +1159,13 @@ "name": "punctuation.definition.parameters.end.tsx" } }, + "patterns": [ + { + "include": "#function-parameters-body" + } + ] + }, + "function-parameters-body": { "patterns": [ { "include": "#comment" @@ -1495,7 +1505,7 @@ "name": "storage.type.namespace.tsx" } }, - "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?<=\\})|(?=;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1529,7 +1539,7 @@ "name": "entity.name.type.alias.tsx" } }, - "end": "(?=[};]|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=\\}|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#comment" @@ -1705,7 +1715,7 @@ "name": "keyword.control.default.tsx" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#expression" @@ -1720,7 +1730,7 @@ "name": "keyword.control.export.tsx" } }, - "end": "(?=;|$|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\btype\\b|\\bvar\\b)", + "end": "(?=$|;|\\babstract\\b|\\basync\\b|\\bclass\\b|\\bconst\\b|\\bdeclare\\b|\\benum\\b|\\bexport\\b|\\bfunction\\b|\\bimport\\b|\\binterface\\b|\\blet\\b|\\bmodule\\b|\\bnamespace\\b|\\breturn\\b|\\btype\\b|\\bvar\\b)", "patterns": [ { "include": "#import-export-declaration" @@ -2039,7 +2049,7 @@ }, { "name": "meta.object.member.tsx", - "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", + "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))", "captures": { "0": { "name": "meta.object-literal.key.tsx" @@ -2119,9 +2129,9 @@ "name": "keyword.operator.ternary.tsx" } }, - "end": "(:)", + "end": "\\s*(:)", "endCaptures": { - "0": { + "1": { "name": "keyword.operator.ternary.tsx" } }, @@ -2185,7 +2195,7 @@ "name": "keyword.operator.new.tsx" } }, - "end": "(?<=\\))|(?=[;),}\\]:]|$|((?)\\s*(async)?(?=\\s*(<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)\\(\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.tsx" + } + }, + "end": "(?<=\\))", + "patterns": [ + { + "include": "#type-parameters" + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "meta.brace.round.tsx" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.tsx" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + } + ] + }, + { + "begin": "(?<=[(=,]|=>)\\s*(async)?\\s*(\\()(?=\\s*$)", + "beginCaptures": { + "1": { + "name": "storage.modifier.async.tsx" + }, + "2": { + "name": "meta.brace.round.tsx" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "meta.brace.round.tsx" + } + }, + "patterns": [ + { + "include": "#expression-inside-possibly-arrow-parens" + } + ] + }, + { + "include": "#possibly-arrow-return-type" + } + ] + }, + "expression-inside-possibly-arrow-parens": { + "patterns": [ + { + "include": "#expressionWithoutIdentifiers" + }, + { + "include": "#function-parameters-body" + }, + { + "include": "#identifiers" + }, + { + "include": "#expressionPunctuations" + } + ] + }, "paren-expression": { "begin": "\\(", "beginCaptures": { @@ -2228,9 +2316,6 @@ "patterns": [ { "include": "#expression" - }, - { - "include": "#punctuation-comma" } ] }, @@ -2713,7 +2798,7 @@ "include": "#object-identifiers" }, { - "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", + "match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*$) |\n # sure shot arrow functions even if => is on new line\n(\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))", "captures": { "1": { "name": "punctuation.accessor.tsx" @@ -2899,6 +2984,28 @@ } }, "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "possibly-arrow-return-type": { + "begin": "(?<=\\))\\s*(:)(?=\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+\\s*=>)", + "beginCaptures": { + "1": { + "name": "meta.arrow.tsx meta.return.type.arrow.tsx keyword.operator.type.annotation.tsx" + } + }, + "end": "(?==>|\\{|(^\\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\\s+))", + "contentName": "meta.arrow.tsx meta.return.type.arrow.tsx", + "patterns": [ + { + "include": "#arrow-return-type-body" + } + ] + }, + "arrow-return-type-body": { "patterns": [ { "begin": "(?<=[:])(?=\\s*\\{)", diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index 7e3b170d968..8c8ba8aea01 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -255,7 +255,10 @@ export default class TypeScriptServiceClientHost { } private getDiagnosticSeverity(diagnostic: Proto.Diagnostic): DiagnosticSeverity { - if (this.reportStyleCheckAsWarnings && this.isStyleCheckDiagnostic(diagnostic.code)) { + if (this.reportStyleCheckAsWarnings + && this.isStyleCheckDiagnostic(diagnostic.code) + && diagnostic.category === PConst.DiagnosticCategory.error + ) { return DiagnosticSeverity.Warning; } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts index e385d5287fd..de2769092e7 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts @@ -12,8 +12,32 @@ import { CompletionList, CompletionItem, CompletionItemKind, TextDocument, Position } from 'vscode'; + suite('languages namespace tests', () => { + test('diagnostics, read & event', function () { + let uri = Uri.file('/foo/bar.txt'); + let col1 = languages.createDiagnosticCollection('foo1'); + col1.set(uri, [new Diagnostic(new Range(0, 0, 0, 12), 'error1')]); + + let col2 = languages.createDiagnosticCollection('foo2'); + col2.set(uri, [new Diagnostic(new Range(0, 0, 0, 12), 'error1')]); + + let diag = languages.getDiagnostics(uri); + assert.equal(diag.length, 2); + + let tuples = languages.getDiagnostics(); + let found = false; + for (let [thisUri,] of tuples) { + if (thisUri.toString() === uri.toString()) { + found = true; + break; + } + } + assert.ok(tuples.length >= 1); + assert.ok(found); + }); + test('diagnostics & CodeActionProvider', function () { class D2 extends Diagnostic { diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 9775a3e7210..63143439fba 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,6 +2,6 @@ # yarn lockfile v1 -typescript@2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624" +typescript@2.8.3-insiders.20180407: + version "2.8.3-insiders.20180407" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.3-insiders.20180407.tgz#915f010e258e51c9539bcf986cfd84d0271d8cab" diff --git a/gulpfile.js b/gulpfile.js index 70aab71c296..db6d924ae73 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -28,8 +28,8 @@ gulp.task('default', ['compile']); // All gulp.task('clean', ['clean-client', 'clean-extensions']); -gulp.task('compile', ['compile-client', 'compile-extensions']); -gulp.task('watch', ['watch-client', 'watch-extensions']); +gulp.task('compile', ['monaco-typecheck', 'compile-client', 'compile-extensions']); +gulp.task('watch', [/* 'monaco-typecheck-watch', */ 'watch-client', 'watch-extensions']); // All Build gulp.task('clean-build', ['clean-client-build', 'clean-extensions-build']); @@ -74,4 +74,4 @@ if (runningEditorTasks) { const build = path.join(__dirname, 'build'); require('glob').sync('gulpfile.*.js', { cwd: build }) .forEach(f => require(`./build/${f}`)); -} \ No newline at end of file +} diff --git a/package.json b/package.json index 988568c52ef..1e15784e1b8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.23.0", - "distro": "6834b79a655ade3dce6df4799a264ff29bff6652", + "distro": "ed36a29ddadc357cdceba6ff5e3e7d5e27893dee", "author": { "name": "Microsoft Corporation" }, @@ -47,7 +47,7 @@ "vscode-nsfw": "1.0.17", "vscode-ripgrep": "^0.8.1", "vscode-textmate": "^3.3.3", - "vscode-xterm": "3.3.0-beta8", + "vscode-xterm": "3.4.0-beta3", "yauzl": "2.8.0" }, "devDependencies": { @@ -113,7 +113,7 @@ "sinon": "^1.17.2", "source-map": "^0.4.4", "tslint": "^5.9.1", - "typescript": "2.7.2", + "typescript": "2.8.1", "typescript-formatter": "7.1.0", "uglify-es": "^3.0.18", "underscore": "^1.8.2", @@ -132,6 +132,6 @@ "optionalDependencies": { "windows-foreground-love": "0.1.0", "windows-mutex": "^0.2.0", - "windows-process-tree": "0.2.0" + "windows-process-tree": "0.2.1" } } diff --git a/scripts/code-cli.bat b/scripts/code-cli.bat index 7bca260314d..f08ddb744e0 100644 --- a/scripts/code-cli.bat +++ b/scripts/code-cli.bat @@ -29,7 +29,7 @@ set ELECTRON_ENABLE_LOGGING=1 set ELECTRON_ENABLE_STACK_DUMPING=1 :: Launch Code -%CODE% --inspect=5874 out\cli.js . %* +%CODE% --debug=5874 out\cli.js . %* popd endlocal diff --git a/scripts/code-cli.sh b/scripts/code-cli.sh index ba2121d9bb9..89e518322fc 100755 --- a/scripts/code-cli.sh +++ b/scripts/code-cli.sh @@ -32,7 +32,7 @@ function code() { VSCODE_DEV=1 \ ELECTRON_ENABLE_LOGGING=1 \ ELECTRON_ENABLE_STACK_DUMPING=1 \ - "$CODE" --inspect=5874 "$ROOT/out/cli.js" . "$@" + "$CODE" --debug=5874 "$ROOT/out/cli.js" . "$@" } code "$@" diff --git a/scripts/code.sh b/scripts/code.sh index 26332faea6c..f6d103ceda5 100755 --- a/scripts/code.sh +++ b/scripts/code.sh @@ -3,10 +3,6 @@ if [[ "$OSTYPE" == "darwin"* ]]; then realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } ROOT=$(dirname "$(dirname "$(realpath "$0")")") - - # On Linux with Electron 2.0.x running out of a VM causes - # a freeze so we only enable this flag on macOS - export ELECTRON_ENABLE_LOGGING=1 else ROOT=$(dirname "$(dirname "$(readlink -f $0)")") fi @@ -44,6 +40,7 @@ function code() { export NODE_ENV=development export VSCODE_DEV=1 export VSCODE_CLI=1 + export ELECTRON_ENABLE_LOGGING=1 export ELECTRON_ENABLE_STACK_DUMPING=1 # Launch Code diff --git a/scripts/test.sh b/scripts/test.sh index ac96627846f..d88a28c5e2d 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -4,10 +4,6 @@ if [[ "$OSTYPE" == "darwin"* ]]; then realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } ROOT=$(dirname $(dirname $(realpath "$0"))) - - # On Linux with Electron 2.0.x running out of a VM causes - # a freeze so we only enable this flag on macOS - export ELECTRON_ENABLE_LOGGING=1 else ROOT=$(dirname $(dirname $(readlink -f $0))) fi @@ -29,6 +25,7 @@ test -d node_modules || yarn node build/lib/electron.js || ./node_modules/.bin/gulp electron # Unit Tests +export ELECTRON_ENABLE_LOGGING=1 if [[ "$OSTYPE" == "darwin"* ]]; then cd $ROOT ; ulimit -n 4096 ; \ "$CODE" \ diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index a051aced93b..daf41dbc736 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Electron 2.0.0-beta.2 +// Type definitions for Electron 1.7.9 // Project: http://electron.atom.io/ // Definitions by: The Electron Team // Definitions: https://github.com/electron/electron-typescript-definitions @@ -58,7 +58,6 @@ declare namespace Electron { dialog: Dialog; DownloadItem: typeof DownloadItem; globalShortcut: GlobalShortcut; - inAppPurchase: InAppPurchase; IncomingMessage: typeof IncomingMessage; ipcMain: IpcMain; Menu: typeof Menu; @@ -95,7 +94,6 @@ declare namespace Electron { const desktopCapturer: DesktopCapturer; const dialog: Dialog; const globalShortcut: GlobalShortcut; - const inAppPurchase: InAppPurchase; const ipcMain: IpcMain; const ipcRenderer: IpcRenderer; type nativeImage = NativeImage; @@ -159,46 +157,6 @@ declare namespace Electron { hasVisibleWindows: boolean) => void): this; removeListener(event: 'activate', listener: (event: Event, hasVisibleWindows: boolean) => void): this; - /** - * Emitted during Handoff after an activity from this device was successfully - * resumed on another one. - */ - on(event: 'activity-was-continued', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; - once(event: 'activity-was-continued', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; - addListener(event: 'activity-was-continued', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; - removeListener(event: 'activity-was-continued', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; /** * Emitted before the application starts closing its windows. Calling * event.preventDefault() will prevent the default behaviour, which is terminating @@ -328,46 +286,6 @@ declare namespace Electron { * Contains app-specific state stored by the activity on another device. */ userInfo: any) => void): this; - /** - * Emitted during Handoff when an activity from a different device fails to be - * resumed. - */ - on(event: 'continue-activity-error', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * A string with the error's localized description. - */ - error: string) => void): this; - once(event: 'continue-activity-error', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * A string with the error's localized description. - */ - error: string) => void): this; - addListener(event: 'continue-activity-error', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * A string with the error's localized description. - */ - error: string) => void): this; - removeListener(event: 'continue-activity-error', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * A string with the error's localized description. - */ - error: string) => void): this; /** * Emitted when the gpu process crashes or is killed. */ @@ -492,49 +410,6 @@ declare namespace Electron { url: string, certificateList: Certificate[], callback: (certificate?: Certificate) => void) => void): this; - /** - * Emitted when Handoff is about to be resumed on another device. If you need to - * update the state to be transferred, you should call event.preventDefault() - * immediately, construct a new userInfo dictionary and call - * app.updateCurrentActiviy() in a timely manner. Otherwise the operation will fail - * and continue-activity-error will be called. - */ - on(event: 'update-activity-state', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; - once(event: 'update-activity-state', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; - addListener(event: 'update-activity-state', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; - removeListener(event: 'update-activity-state', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string, - /** - * Contains app-specific state stored by the activity. - */ - userInfo: any) => void): this; /** * Emitted when a new webContents is created. */ @@ -546,31 +421,6 @@ declare namespace Electron { webContents: WebContents) => void): this; removeListener(event: 'web-contents-created', listener: (event: Event, webContents: WebContents) => void): this; - /** - * Emitted during Handoff before an activity from a different device wants to be - * resumed. You should call event.preventDefault() if you want to handle this - * event. - */ - on(event: 'will-continue-activity', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string) => void): this; - once(event: 'will-continue-activity', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string) => void): this; - addListener(event: 'will-continue-activity', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string) => void): this; - removeListener(event: 'will-continue-activity', listener: (event: Event, - /** - * A string identifying the activity. Maps to . - */ - type: string) => void): this; /** * Emitted when the application has finished basic startup. On Windows and Linux, * the will-finish-launching event is the same as the ready event; on macOS, this @@ -632,7 +482,7 @@ declare namespace Electron { */ enableMixedSandbox(): void; /** - * Exits immediately with exitCode. exitCode defaults to 0. All windows will be + * Exits immediately with exitCode. exitCode defaults to 0. All windows will be * closed immediately without asking user and the before-quit and will-quit events * will not be emitted. */ @@ -642,6 +492,7 @@ declare namespace Electron { * the active app. On Windows, focuses on the application's first window. */ focus(): void; + getAppMemoryInfo(): ProcessMetric[]; getAppMetrics(): ProcessMetric[]; getAppPath(): string; getBadgeCount(): number; @@ -650,12 +501,12 @@ declare namespace Electron { * Fetches a path's associated icon. On Windows, there a 2 kinds of icons: On Linux * and macOS, icons depend on the application associated with file mime type. */ - getFileIcon(path: string, callback: (error: Error, icon: NativeImage) => void): void; + getFileIcon(path: string, options: FileIconOptions, callback: (error: Error, icon: NativeImage) => void): void; /** * Fetches a path's associated icon. On Windows, there a 2 kinds of icons: On Linux * and macOS, icons depend on the application associated with file mime type. */ - getFileIcon(path: string, options: FileIconOptions, callback: (error: Error, icon: NativeImage) => void): void; + getFileIcon(path: string, callback: (error: Error, icon: NativeImage) => void): void; getGPUFeatureStatus(): GPUFeatureStatus; getJumpListSettings(): JumpListSettings; /** @@ -666,7 +517,8 @@ declare namespace Electron { getLocale(): string; /** * If you provided path and args options to app.setLoginItemSettings then you need - * to pass the same arguments here for openAtLogin to be set correctly. + * to pass the same arguments here for openAtLogin to be set correctly. Note: This + * API has no effect on MAS builds. */ getLoginItemSettings(options?: LoginItemSettingsOptions): LoginItemSettings; /** @@ -692,10 +544,6 @@ declare namespace Electron { * net_error_list. */ importCertificate(options: ImportCertificateOptions, callback: (result: number) => void): void; - /** - * Invalidates the current Handoff user activity. - */ - invalidateCurrentActivity(type: string): void; isAccessibilitySupportEnabled(): boolean; /** * This method checks if the current executable is the default handler for a @@ -707,7 +555,6 @@ declare namespace Electron { * the Windows Registry and LSCopyDefaultHandlerForURLScheme internally. */ isDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean; - isInApplicationsFolder(): boolean; isReady(): boolean; isUnityRunning(): boolean; /** @@ -731,15 +578,6 @@ declare namespace Electron { * instance starts: */ makeSingleInstance(callback: (argv: string[], workingDirectory: string) => void): boolean; - /** - * No confirmation dialog will be presented by default, if you wish to allow the - * user to confirm the operation you may do so using the dialog API. NOTE: This - * method throws errors if anything other than the user causes the move to fail. - * For instance if the user cancels the authorization dialog this method returns - * false. If we fail to perform the copy then this method will throw an error. The - * message in the error should be informative and tell you exactly what went wrong - */ - moveToApplicationsFolder(): boolean; /** * Try to close all windows. The before-quit event will be emitted first. If all * windows are successfully closed, the will-quit event will be emitted and by @@ -777,15 +615,6 @@ declare namespace Electron { * .plist file. See the Apple docs for more details. */ setAboutPanelOptions(options: AboutPanelOptionsOptions): void; - /** - * Manually enables Chrome's accessibility support, allowing to expose - * accessibility switch to users in application settings. - * https://www.chromium.org/developers/design-documents/accessibility for more - * details. Disabled by default. Note: Rendering accessibility tree can - * significantly affect the performance of your app. It should not be enabled by - * default. - */ - setAccessibilitySupportEnabled(enabled: boolean): void; /** * Changes the Application User Model ID to id. */ @@ -831,7 +660,8 @@ declare namespace Electron { /** * Set the app's login item settings. To work with Electron's autoUpdater on * Windows, which uses Squirrel, you'll want to set the launch path to Update.exe, - * and pass arguments that specify your application name. For example: + * and pass arguments that specify your application name. For example: Note: This + * API has no effect on MAS builds. */ setLoginItemSettings(settings: Settings): void; /** @@ -864,18 +694,6 @@ declare namespace Electron { * them. */ show(): void; - /** - * Start accessing a security scoped resource. With this method electron - * applications that are packaged for the Mac App Store may reach outside their - * sandbox to access files chosen by the user. See Apple's documentation for a - * description of how this system works. - */ - startAccessingSecurityScopedResource(bookmarkData: string): Function; - /** - * Updates the current activity if its type matches type, merging the entries from - * userInfo into its current userInfo dictionary. - */ - updateCurrentActivity(type: string, userInfo: any): void; commandLine: CommandLine; dock: Dock; } @@ -945,18 +763,16 @@ declare namespace Electron { getFeedURL(): string; /** * Restarts the app and installs the update after it has been downloaded. It should - * only be called after update-downloaded has been emitted. Under the hood calling - * autoUpdater.quitAndInstall() will close all application windows first, and - * automatically call app.quit() after all windows have been closed. Note: If the - * application is quit without calling this API after the update-downloaded event - * has been emitted, the application will still be replaced by the updated one on - * the next run. + * only be called after update-downloaded has been emitted. Note: + * autoUpdater.quitAndInstall() will close all application windows first and only + * emit before-quit event on app after that. This is different from the normal quit + * event sequence. */ quitAndInstall(): void; /** * Sets the url and initialize the auto updater. */ - setFeedURL(options: FeedURLOptions): void; + setFeedURL(url: string, requestHeaders?: any): void; } interface BluetoothDevice { @@ -973,8 +789,6 @@ declare namespace Electron { constructor(options?: BrowserViewConstructorOptions); static fromId(id: number): BrowserView; - static fromWebContents(webContents: WebContents): BrowserView | null; - static getAllViews(): BrowserView[]; setAutoResize(options: AutoResizeOptions): void; setBackgroundColor(color: string): void; /** @@ -1017,11 +831,7 @@ declare namespace Electron { * cancel the close. Usually you would want to use the beforeunload handler to * decide whether the window should be closed, which will also be called when the * window is reloaded. In Electron, returning any value other than undefined would - * cancel the close. For example: Note: There is a subtle difference between the - * behaviors of window.onbeforeunload = handler and - * window.addEventListener('beforeunload', handler). It is recommended to always - * set the event.returnValue explicitly, instead of just returning a value, as the - * former works more consistently within Electron. + * cancel the close. For example: */ on(event: 'close', listener: (event: Event) => void): this; once(event: 'close', listener: (event: Event) => void): this; @@ -1246,7 +1056,6 @@ declare namespace Electron { * This API cannot be called before the ready event of the app module is emitted. */ static addExtension(path: string): void; - static fromBrowserView(browserView: BrowserView): BrowserWindow | null; static fromId(id: number): BrowserWindow; static fromWebContents(webContents: WebContents): BrowserWindow; static getAllWindows(): BrowserWindow[]; @@ -1271,10 +1080,6 @@ declare namespace Electron { * ready event of the app module is emitted. */ static removeExtension(name: string): void; - /** - * Adds a window as a tab on this window, after the tab for the window instance. - */ - addTabbedWindow(browserWindow: BrowserWindow): void; /** * Removes focus from the window. */ @@ -1318,11 +1123,6 @@ declare namespace Electron { focus(): void; focusOnWebView(): void; getBounds(): Rectangle; - /** - * Note: The BrowserView API is currently experimental and may change or be removed - * in future Electron releases. - */ - getBrowserView(): BrowserView | null; getChildWindows(): BrowserWindow[]; getContentBounds(): Rectangle; getContentSize(): number[]; @@ -1333,7 +1133,6 @@ declare namespace Electron { * (unsigned long) on Linux. */ getNativeWindowHandle(): Buffer; - getOpacity(): number; getParentWindow(): BrowserWindow; getPosition(): number[]; getRepresentedFilename(): string; @@ -1385,18 +1184,12 @@ declare namespace Electron { */ isMovable(): boolean; isResizable(): boolean; - isSimpleFullScreen(): boolean; isVisible(): boolean; /** * Note: This API always returns false on Windows. */ isVisibleOnAllWorkspaces(): boolean; isWindowMessageHooked(message: number): boolean; - /** - * Same as webContents.loadFile, filePath should be a path to an HTML file relative - * to the root of your application. See the webContents docs for more information. - */ - loadFile(filePath: string): void; /** * Same as webContents.loadURL(url[, options]). The url can be a remote address * (e.g. http://) or a path to a local HTML file using the file:// protocol. To @@ -1410,21 +1203,11 @@ declare namespace Electron { * being displayed already. */ maximize(): void; - /** - * Merges all windows into one window with multiple tabs when native tabs are - * enabled and there is more than one open window. - */ - mergeAllWindows(): void; /** * Minimizes the window. On some platforms the minimized window will be shown in * the Dock. */ minimize(): void; - /** - * Moves the current tab into a new window if native tabs are enabled and there is - * more than one tab in the current window. - */ - moveTabToNewWindow(): void; /** * Uses Quick Look to preview a file at a given path. */ @@ -1437,16 +1220,6 @@ declare namespace Electron { * Restores the window from minimized state to its previous state. */ restore(): void; - /** - * Selects the next tab when native tabs are enabled and there are other tabs in - * the window. - */ - selectNextTab(): void; - /** - * Selects the previous tab when native tabs are enabled and there are other tabs - * in the window. - */ - selectPreviousTab(): void; /** * Sets whether the window should show always on top of other windows. After * setting this, the window is still a normal window, not a toolbox window which @@ -1488,6 +1261,10 @@ declare namespace Electron { * Resizes and moves the window to the supplied bounds */ setBounds(bounds: Rectangle, animate?: boolean): void; + /** + * Note: The BrowserView API is currently experimental and may change or be removed + * in future Electron releases. + */ setBrowserView(browserView: BrowserView): void; /** * Sets whether the window can be manually closed by user. On Linux does nothing. @@ -1513,10 +1290,6 @@ declare namespace Electron { * bar will become gray when set to true. */ setDocumentEdited(edited: boolean): void; - /** - * Disable or enable the window. - */ - setEnabled(enable: boolean): void; /** * Changes whether the window can be focused. */ @@ -1543,7 +1316,7 @@ declare namespace Electron { * window will be passed to the window below this window, but if this window has * focus, it will still receive keyboard events. */ - setIgnoreMouseEvents(ignore: boolean, options?: IgnoreMouseEventsOptions): void; + setIgnoreMouseEvents(ignore: boolean): void; /** * Enters or leaves the kiosk mode. */ @@ -1580,10 +1353,6 @@ declare namespace Electron { * Sets whether the window can be moved by user. On Linux does nothing. */ setMovable(movable: boolean): void; - /** - * Sets the opacity of the window. On Linux does nothing. - */ - setOpacity(opacity: number): void; /** * Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to * convey some sort of application status or to passively notify the user. @@ -1624,11 +1393,6 @@ declare namespace Electron { * HTML-rendered toolbar. For example: */ setSheetOffset(offsetY: number, offsetX?: number): void; - /** - * Enters or leaves simple fullscreen mode. Simple fullscreen mode emulates the - * native fullscreen behavior found in versions of Mac OS X prior to Lion (10.7). - */ - setSimpleFullScreen(flag: boolean): void; /** * Resizes the window to width and height. */ @@ -1692,11 +1456,6 @@ declare namespace Electron { * Shows the window but doesn't focus on it. */ showInactive(): void; - /** - * Toggles the visibility of the tab bar if native tabs are enabled and there is - * only one tab in the current window. - */ - toggleTabBar(): void; /** * Unhooks all of the window messages. */ @@ -1930,7 +1689,7 @@ declare namespace Electron { * An object representing the HTTP response message. */ response: IncomingMessage) => void): this; - constructor(options: 'method' | 'url' | 'session' | 'partition' | 'protocol' | 'host' | 'hostname' | 'port' | 'path' | 'redirect'); + constructor(options: any | string); /** * Cancels an ongoing HTTP transaction. If the request has already emitted the * close event, the abort operation will have no effect. Otherwise an ongoing event @@ -2158,7 +1917,7 @@ declare namespace Electron { */ on(event: 'changed', listener: (event: Event, /** - * The cookie that was changed. + * The cookie that was changed */ cookie: Cookie, /** @@ -2171,7 +1930,7 @@ declare namespace Electron { removed: boolean) => void): this; once(event: 'changed', listener: (event: Event, /** - * The cookie that was changed. + * The cookie that was changed */ cookie: Cookie, /** @@ -2184,7 +1943,7 @@ declare namespace Electron { removed: boolean) => void): this; addListener(event: 'changed', listener: (event: Event, /** - * The cookie that was changed. + * The cookie that was changed */ cookie: Cookie, /** @@ -2197,7 +1956,7 @@ declare namespace Electron { removed: boolean) => void): this; removeListener(event: 'changed', listener: (event: Event, /** - * The cookie that was changed. + * The cookie that was changed */ cookie: Cookie, /** @@ -2213,8 +1972,8 @@ declare namespace Electron { */ flushStore(callback: Function): void; /** - * Sends a request to get all cookies matching filter, callback will be called with - * callback(error, cookies) on complete. + * Sends a request to get all cookies matching details, callback will be called + * with callback(error, cookies) on complete. */ get(filter: Filter, callback: (error: Error, cookies: Cookie[]) => void): void; /** @@ -2235,7 +1994,7 @@ declare namespace Electron { /** * The number of average idle cpu wakeups per second since the last call to - * getCPUUsage. First call returns 0. Will always return 0 on Windows. + * getCPUUsage. First call returns 0. */ idleWakeupsPerSecond: number; /** @@ -2248,31 +2007,19 @@ declare namespace Electron { // Docs: http://electron.atom.io/docs/api/structures/crash-report - date: Date; - id: string; + date: string; + ID: number; } interface CrashReporter extends EventEmitter { // Docs: http://electron.atom.io/docs/api/crash-reporter - /** - * Set an extra parameter to be sent with the crash report. The values specified - * here will be sent in addition to any values set via the extra option when start - * was called. This API is only available on macOS, if you need to add/update extra - * parameters on Linux and Windows after your first call to start you can call - * start again with the updated extra options. - */ - addExtraParameter(key: string, value: string): void; /** * Returns the date and ID of the last crash report. If no crash reports have been * sent or the crash reporter has not been started, null is returned. */ getLastCrashReport(): CrashReport; - /** - * See all of the current parameters being passed to the crash reporter. - */ - getParameters(): void; /** * Returns all uploaded crash reports. Each report contains the date and uploaded * ID. @@ -2283,10 +2030,13 @@ declare namespace Electron { */ getUploadToServer(): boolean; /** - * Remove a extra parameter from the current set of parameters so that it will not - * be sent with the crash report. + * Set an extra parameter to be sent with the crash report. The values specified + * here will be sent in addition to any values set via the extra option when start + * was called. This API is only available on macOS, if you need to add/update extra + * parameters on Linux and Windows after your first call to start you can call + * start again with the updated extra options. */ - removeExtraParameter(key: string): void; + setExtraParameter(key: string, value: string): void; /** * This would normally be controlled by user preferences. This has no effect if * called before start is called. Note: This API can only be called from the main @@ -2307,7 +2057,7 @@ declare namespace Electron { * well. This will start the process that will monitor and send the crash reports. * Replace submitURL, productName and crashesDirectory with appropriate values. * Note: If you need send additional/updated extra parameters after your first call - * start you can call addExtraParameter on macOS or call start again with the + * start you can call setExtraParameter on macOS or call start again with the * new/updated extra parameters on Linux and Windows. Note: On macOS, Electron uses * a new crashpad client for crash collection and reporting. If you want to enable * crash reporting, initializing crashpad from the main process using @@ -2475,7 +2225,7 @@ declare namespace Electron { /** * Displays a modal dialog that shows an error message. This API can be called * safely before the ready event the app module emits, it is usually used to report - * errors in early stage of startup. If called before the app readyevent on Linux, + * errors in early stage of startup. If called before the app readyevent on Linux, * the message will be emitted to stderr, and no GUI dialog will appear. */ showErrorBox(title: string, content: string): void; @@ -2503,11 +2253,11 @@ declare namespace Electron { * dots (e.g. 'png' is good but '.png' and '*.png' are bad). To show all files, use * the '*' wildcard (no other wildcard is supported). If a callback is passed, the * API call will be asynchronous and the result will be passed via - * callback(filenames). Note: On Windows and Linux an open dialog can not be both a + * callback(filenames) Note: On Windows and Linux an open dialog can not be both a * file selector and a directory selector, so if you set properties to ['openFile', * 'openDirectory'] on these platforms, a directory selector will be shown. */ - showOpenDialog(browserWindow: BrowserWindow, options: OpenDialogOptions, callback?: (filePaths: string[], bookmarks: string[]) => void): string[]; + showOpenDialog(browserWindow: BrowserWindow, options: OpenDialogOptions, callback?: (filePaths: string[]) => void): string[]; /** * The browserWindow argument allows the dialog to attach itself to a parent * window, making it modal. The filters specifies an array of file types that can @@ -2516,27 +2266,27 @@ declare namespace Electron { * dots (e.g. 'png' is good but '.png' and '*.png' are bad). To show all files, use * the '*' wildcard (no other wildcard is supported). If a callback is passed, the * API call will be asynchronous and the result will be passed via - * callback(filenames). Note: On Windows and Linux an open dialog can not be both a + * callback(filenames) Note: On Windows and Linux an open dialog can not be both a * file selector and a directory selector, so if you set properties to ['openFile', * 'openDirectory'] on these platforms, a directory selector will be shown. */ - showOpenDialog(options: OpenDialogOptions, callback?: (filePaths: string[], bookmarks: string[]) => void): string[]; + showOpenDialog(options: OpenDialogOptions, callback?: (filePaths: string[]) => void): string[]; /** * The browserWindow argument allows the dialog to attach itself to a parent * window, making it modal. The filters specifies an array of file types that can * be displayed, see dialog.showOpenDialog for an example. If a callback is passed, * the API call will be asynchronous and the result will be passed via - * callback(filename). + * callback(filename) */ - showSaveDialog(browserWindow: BrowserWindow, options: SaveDialogOptions, callback?: (filename: string, bookmark: string) => void): string; + showSaveDialog(browserWindow: BrowserWindow, options: SaveDialogOptions, callback?: (filename: string) => void): string; /** * The browserWindow argument allows the dialog to attach itself to a parent * window, making it modal. The filters specifies an array of file types that can * be displayed, see dialog.showOpenDialog for an example. If a callback is passed, * the API call will be asynchronous and the result will be passed via - * callback(filename). + * callback(filename) */ - showSaveDialog(options: SaveDialogOptions, callback?: (filename: string, bookmark: string) => void): string; + showSaveDialog(options: SaveDialogOptions, callback?: (filename: string) => void): string; } interface Display { @@ -2575,54 +2325,33 @@ declare namespace Electron { * download that can't be resumed. The state can be one of following: */ on(event: 'done', listener: (event: Event, - /** - * Can be `completed`, `cancelled` or `interrupted`. - */ - state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + state: string) => void): this; once(event: 'done', listener: (event: Event, - /** - * Can be `completed`, `cancelled` or `interrupted`. - */ - state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + state: string) => void): this; addListener(event: 'done', listener: (event: Event, - /** - * Can be `completed`, `cancelled` or `interrupted`. - */ - state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + state: string) => void): this; removeListener(event: 'done', listener: (event: Event, - /** - * Can be `completed`, `cancelled` or `interrupted`. - */ - state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + state: string) => void): this; /** * Emitted when the download has been updated and is not done. The state can be one * of following: */ on(event: 'updated', listener: (event: Event, - /** - * Can be `progressing` or `interrupted`. - */ - state: ('progressing' | 'interrupted')) => void): this; + state: string) => void): this; once(event: 'updated', listener: (event: Event, - /** - * Can be `progressing` or `interrupted`. - */ - state: ('progressing' | 'interrupted')) => void): this; + state: string) => void): this; addListener(event: 'updated', listener: (event: Event, - /** - * Can be `progressing` or `interrupted`. - */ - state: ('progressing' | 'interrupted')) => void): this; + state: string) => void): this; removeListener(event: 'updated', listener: (event: Event, - /** - * Can be `progressing` or `interrupted`. - */ - state: ('progressing' | 'interrupted')) => void): this; + state: string) => void): this; /** * Cancels the download operation. */ cancel(): void; - canResume(): boolean; + /** + * Resumes Boolean - Whether the download can resume. + */ + canResume(): void; getContentDisposition(): string; getETag(): string; /** @@ -2762,38 +2491,6 @@ declare namespace Electron { webgl2: string; } - interface InAppPurchase extends EventEmitter { - - // Docs: http://electron.atom.io/docs/api/in-app-purchase - - /** - * Emitted when one or more transactions have been updated. - */ - on(event: 'transactions-updated', listener: (event: Event, - /** - * Array of transactions. - */ - transactions: Transaction[]) => void): this; - once(event: 'transactions-updated', listener: (event: Event, - /** - * Array of transactions. - */ - transactions: Transaction[]) => void): this; - addListener(event: 'transactions-updated', listener: (event: Event, - /** - * Array of transactions. - */ - transactions: Transaction[]) => void): this; - removeListener(event: 'transactions-updated', listener: (event: Event, - /** - * Array of transactions. - */ - transactions: Transaction[]) => void): this; - canMakePayments(): boolean; - getReceiptURL(): string; - purchaseProduct(productID: string, quantity?: number, callback?: (isProductValid: boolean) => void): void; - } - class IncomingMessage extends EventEmitter { // Docs: http://electron.atom.io/docs/api/incoming-message @@ -2927,7 +2624,7 @@ declare namespace Electron { /** * Removes all listeners, or those of the specified channel. */ - removeAllListeners(channel: string): this; + removeAllListeners(channel?: string): this; /** * Removes the specified listener from the listener array for the specified * channel. @@ -2949,10 +2646,6 @@ declare namespace Electron { * renderer process, unless you know what you are doing you should never use it. */ sendSync(channel: string, ...args: any[]): any; - /** - * Sends a message to a window with windowid via channel. - */ - sendTo(windowId: number, channel: string, ...args: any[]): void; /** * Like ipcRenderer.send but the event will be sent to the element in the * host page instead of the main process. @@ -3067,20 +2760,6 @@ declare namespace Electron { // Docs: http://electron.atom.io/docs/api/menu - /** - * Emitted when a popup is closed either manually or with menu.closePopup(). - */ - on(event: 'menu-will-close', listener: (event: Event) => void): this; - once(event: 'menu-will-close', listener: (event: Event) => void): this; - addListener(event: 'menu-will-close', listener: (event: Event) => void): this; - removeListener(event: 'menu-will-close', listener: (event: Event) => void): this; - /** - * Emitted when menu.popup() is called. - */ - on(event: 'menu-will-show', listener: (event: Event) => void): this; - once(event: 'menu-will-show', listener: (event: Event) => void): this; - addListener(event: 'menu-will-show', listener: (event: Event) => void): this; - removeListener(event: 'menu-will-show', listener: (event: Event) => void): this; constructor(); /** * Generally, the template is just an array of options for constructing a MenuItem. @@ -3093,7 +2772,7 @@ declare namespace Electron { * Note: The returned Menu instance doesn't support dynamic addition or removal of * menu items. Instance properties can still be dynamically modified. */ - static getApplicationMenu(): Menu | null; + static getApplicationMenu(): Menu; /** * Sends the action to the first responder of application. This is used for * emulating default macOS menu behaviors. Usually you would just use the role @@ -3107,7 +2786,7 @@ declare namespace Electron { * Windows and Linux but has no effect on macOS. Note: This API has to be called * after the ready event of app module. */ - static setApplicationMenu(menu: Menu | null): void; + static setApplicationMenu(menu: Menu): void; /** * Appends the menuItem to the menu. */ @@ -3116,15 +2795,14 @@ declare namespace Electron { * Closes the context menu in the browserWindow. */ closePopup(browserWindow?: BrowserWindow): void; - getMenuItemById(id: string): MenuItem; /** * Inserts the menuItem to the pos position of the menu. */ insert(pos: number, menuItem: MenuItem): void; /** - * Pops up this menu as a context menu in the BrowserWindow. + * Pops up this menu as a context menu in the browserWindow. */ - popup(options: PopupOptions): void; + popup(browserWindow?: BrowserWindow, options?: PopupOptions): void; items: MenuItem[]; } @@ -3170,13 +2848,6 @@ declare namespace Electron { * Creates a new NativeImage instance from dataURL. */ static createFromDataURL(dataURL: string): NativeImage; - /** - * Creates a new NativeImage instance from the NSImage that maps to the given image - * name. See NSImageName for a list of possible values. The hslShift is applied to - * the image with the following rules This means that [-1, 0, 1] will make the - * image completely white and [-1, 1, 0] will make the image completely black. - */ - static createFromNamedImage(imageName: string, hslShift: number[]): NativeImage; /** * Creates a new NativeImage instance from a file located at path. This method * returns an empty image if the path does not exist, cannot be read, or is not a @@ -3240,22 +2911,22 @@ declare namespace Electron { on(event: 'action', listener: (event: Event, /** - * The index of the action that was activated. + * The index of the action that was activated */ index: number) => void): this; once(event: 'action', listener: (event: Event, /** - * The index of the action that was activated. + * The index of the action that was activated */ index: number) => void): this; addListener(event: 'action', listener: (event: Event, /** - * The index of the action that was activated. + * The index of the action that was activated */ index: number) => void): this; removeListener(event: 'action', listener: (event: Event, /** - * The index of the action that was activated. + * The index of the action that was activated */ index: number) => void): this; /** @@ -3267,7 +2938,7 @@ declare namespace Electron { removeListener(event: 'click', listener: (event: Event) => void): this; /** * Emitted when the notification is closed by manual intervention from the user. - * This event is not guaranteed to be emitted in all cases where the notification + * This event is not guarunteed to be emitted in all cases where the notification * is closed. */ on(event: 'close', listener: (event: Event) => void): this; @@ -3280,22 +2951,22 @@ declare namespace Electron { */ on(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field. + * The string the user entered into the inline reply field */ reply: string) => void): this; once(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field. + * The string the user entered into the inline reply field */ reply: string) => void): this; addListener(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field. + * The string the user entered into the inline reply field */ reply: string) => void): this; removeListener(event: 'reply', listener: (event: Event, /** - * The string the user entered into the inline reply field. + * The string the user entered into the inline reply field */ reply: string) => void): this; /** @@ -3309,17 +2980,11 @@ declare namespace Electron { removeListener(event: 'show', listener: (event: Event) => void): this; constructor(options: NotificationConstructorOptions); static isSupported(): boolean; - /** - * Dismisses the notification. - */ - close(): void; /** * Immediately shows the notification to the user, please note this means unlike * the HTML5 Notification implementation, simply instantiating a new Notification * does not immediately show it to the user, you need to call this method before - * the OS will display it. If the notification has been shown before, this method - * will dismiss the previously shown notification and create a new one with - * identical properties. + * the OS will display it. */ show(): void; } @@ -3371,16 +3036,6 @@ declare namespace Electron { once(event: 'resume', listener: Function): this; addListener(event: 'resume', listener: Function): this; removeListener(event: 'resume', listener: Function): this; - /** - * Emitted when the system is about to reboot or shut down. If the event handler - * invokes e.preventDefault(), Electron will attempt to delay system shutdown in - * order for the app to exit cleanly. If e.preventDefault() is called, the app - * should exit as soon as possible by calling something like app.quit(). - */ - on(event: 'shutdown', listener: Function): this; - once(event: 'shutdown', listener: Function): this; - addListener(event: 'shutdown', listener: Function): this; - removeListener(event: 'shutdown', listener: Function): this; /** * Emitted when the system is suspending. */ @@ -3463,11 +3118,6 @@ declare namespace Electron { * sends a new HTTP request as a response. */ interceptHttpProtocol(scheme: string, handler: (request: InterceptHttpProtocolRequest, callback: (redirectRequest: RedirectRequest) => void) => void, completion?: (error: Error) => void): void; - /** - * Same as protocol.registerStreamProtocol, except that it replaces an existing - * protocol handler. - */ - interceptStreamProtocol(scheme: string, handler: (request: InterceptStreamProtocolRequest, callback: (stream?: ReadableStream | StreamProtocolResponse) => void) => void, completion?: (error: Error) => void): void; /** * Intercepts scheme protocol and uses handler as the protocol's new handler which * sends a String as a response. @@ -3528,15 +3178,6 @@ declare namespace Electron { * the ready event of the app module gets emitted. */ registerStandardSchemes(schemes: string[], options?: RegisterStandardSchemesOptions): void; - /** - * Registers a protocol of scheme that will send a Readable as a response. The - * usage is similar to the other register{Any}Protocol, except that the callback - * should be called with either a Readable object or an object that has the data, - * statusCode, and headers properties. Example: It is possible to pass any object - * that implements the readable stream API (emits data/end/error events). For - * example, here's how a file could be returned: - */ - registerStreamProtocol(scheme: string, handler: (request: RegisterStreamProtocolRequest, callback: (stream?: ReadableStream | StreamProtocolResponse) => void) => void, completion?: (error: Error) => void): void; /** * Registers a protocol of scheme that will send a String as a response. The usage * is the same with registerFileProtocol, except that the callback should be called @@ -3739,7 +3380,7 @@ declare namespace Electron { * options, you have to ensure the Session with the partition has never been used * before. There is no way to change the options of an existing Session object. */ - static fromPartition(partition: string, options?: FromPartitionOptions): Session; + static fromPartition(partition: string, options: FromPartitionOptions): Session; /** * A Session object, the default session object of the app. */ @@ -3803,12 +3444,11 @@ declare namespace Electron { * Writes any unwritten DOMStorage data to disk. */ flushStorageData(): void; - getBlobData(identifier: string, callback: (result: Buffer) => void): void; + getBlobData(identifier: string, callback: (result: Buffer) => void): Blob; /** * Callback is invoked with the session's current cache size. */ getCacheSize(callback: (size: number) => void): void; - getPreloads(): string[]; getUserAgent(): string; /** * Resolves the proxy information for url. The callback will be called with @@ -3831,14 +3471,9 @@ declare namespace Electron { /** * Sets the handler which can be used to respond to permission requests for the * session. Calling callback(true) will allow the permission and callback(false) - * will reject it. To clear the handler, call setPermissionRequestHandler(null). + * will reject it. */ - setPermissionRequestHandler(handler: (webContents: WebContents, permission: string, callback: (permissionGranted: boolean) => void, details: PermissionRequestHandlerDetails) => void | null): void; - /** - * Adds scripts that will be executed on ALL web contents that are associated with - * this session just before normal preload scripts run. - */ - setPreloads(preloads: string[]): void; + setPermissionRequestHandler(handler: (webContents: WebContents, permission: string, callback: (permissionGranted: boolean) => void) => void): void; /** * Sets the proxy settings. When pacScript and proxyRules are provided together, * the proxyRules option is ignored and pacScript configuration is applied. The @@ -3943,24 +3578,6 @@ declare namespace Electron { width: number; } - interface StreamProtocolResponse { - - // Docs: http://electron.atom.io/docs/api/structures/stream-protocol-response - - /** - * A Node.js readable stream representing the response body - */ - data: ReadableStream; - /** - * An object containing the response headers - */ - headers: Headers; - /** - * The HTTP response code - */ - statusCode: number; - } - interface SystemPreferences extends EventEmitter { // Docs: http://electron.atom.io/docs/api/system-preferences @@ -4016,7 +3633,7 @@ declare namespace Electron { getAccentColor(): string; getColor(color: '3d-dark-shadow' | '3d-face' | '3d-highlight' | '3d-light' | '3d-shadow' | 'active-border' | 'active-caption' | 'active-caption-gradient' | 'app-workspace' | 'button-text' | 'caption-text' | 'desktop' | 'disabled-text' | 'highlight' | 'highlight-text' | 'hotlight' | 'inactive-border' | 'inactive-caption' | 'inactive-caption-gradient' | 'inactive-caption-text' | 'info-background' | 'info-text' | 'menu' | 'menu-highlight' | 'menubar' | 'menu-text' | 'scrollbar' | 'window' | 'window-frame' | 'window-text'): string; /** - * Some popular key and types are: + * This API uses NSUserDefaults on macOS. Some popular key and types are: */ getUserDefault(key: string, type: 'string' | 'boolean' | 'integer' | 'float' | 'double' | 'url' | 'array' | 'dictionary'): any; /** @@ -4038,22 +3655,14 @@ declare namespace Electron { */ postNotification(event: string, userInfo: any): void; /** - * Add the specified defaults to your application's NSUserDefaults. - */ - registerDefaults(defaults: any): void; - /** - * Removes the key in NSUserDefaults. This can be used to restore the default or - * global value of a key previously set with setUserDefault. - */ - removeUserDefault(key: string): void; - /** - * Set the value of key in NSUserDefaults. Note that type should match actual type - * of value. An exception is thrown if they don't. Some popular key and types are: + * Set the value of key in system preferences. Note that type should match actual + * type of value. An exception is thrown if they don't. This API uses + * NSUserDefaults on macOS. Some popular key and types are: */ setUserDefault(key: string, type: string, value: string): void; /** * Same as subscribeNotification, but uses NSNotificationCenter for local defaults. - * This is necessary for events such as NSUserDefaultsDidChangeNotification. + * This is necessary for events such as NSUserDefaultsDidChangeNotification */ subscribeLocalNotification(event: string, callback: (event: string, userInfo: any) => void): void; /** @@ -4221,7 +3830,7 @@ declare namespace Electron { // Docs: http://electron.atom.io/docs/api/touch-bar constructor(options: TouchBarConstructorOptions); - escapeItem: (TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer | null); + escapeItem: any; static TouchBarButton: typeof TouchBarButton; static TouchBarColorPicker: typeof TouchBarColorPicker; static TouchBarGroup: typeof TouchBarGroup; @@ -4233,23 +3842,6 @@ declare namespace Electron { static TouchBarSpacer: typeof TouchBarSpacer; } - interface Transaction { - - // Docs: http://electron.atom.io/docs/api/structures/transaction - - errorCode: number; - errorMessage: string; - originalTransactionIdentifier: string; - payment: Payment; - transactionDate: string; - transactionIdentifier: string; - /** - * The transaction sate ("purchasing", "purchased", "failed", "restored", or - * "deferred") - */ - transactionState: string; - } - class Tray extends EventEmitter { // Docs: http://electron.atom.io/docs/api/tray @@ -4281,61 +3873,45 @@ declare namespace Electron { */ on(event: 'click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ - bounds: Rectangle, - /** - * The position of the event. - */ - position: Point) => void): this; + bounds: Rectangle) => void): this; once(event: 'click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ - bounds: Rectangle, - /** - * The position of the event. - */ - position: Point) => void): this; + bounds: Rectangle) => void): this; addListener(event: 'click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ - bounds: Rectangle, - /** - * The position of the event. - */ - position: Point) => void): this; + bounds: Rectangle) => void): this; removeListener(event: 'click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ - bounds: Rectangle, - /** - * The position of the event. - */ - position: Point) => void): this; + bounds: Rectangle) => void): this; /** * Emitted when the tray icon is double clicked. */ on(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; once(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; addListener(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; removeListener(event: 'double-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; /** @@ -4394,22 +3970,22 @@ declare namespace Electron { */ on(event: 'drop-text', listener: (event: Event, /** - * the dropped text string. + * the dropped text string */ text: string) => void): this; once(event: 'drop-text', listener: (event: Event, /** - * the dropped text string. + * the dropped text string */ text: string) => void): this; addListener(event: 'drop-text', listener: (event: Event, /** - * the dropped text string. + * the dropped text string */ text: string) => void): this; removeListener(event: 'drop-text', listener: (event: Event, /** - * the dropped text string. + * the dropped text string */ text: string) => void): this; /** @@ -4417,22 +3993,22 @@ declare namespace Electron { */ on(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event. + * The position of the event */ position: Point) => void): this; once(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event. + * The position of the event */ position: Point) => void): this; addListener(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event. + * The position of the event */ position: Point) => void): this; removeListener(event: 'mouse-enter', listener: (event: Event, /** - * The position of the event. + * The position of the event */ position: Point) => void): this; /** @@ -4440,45 +4016,22 @@ declare namespace Electron { */ on(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event. + * The position of the event */ position: Point) => void): this; once(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event. + * The position of the event */ position: Point) => void): this; addListener(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event. + * The position of the event */ position: Point) => void): this; removeListener(event: 'mouse-leave', listener: (event: Event, /** - * The position of the event. - */ - position: Point) => void): this; - /** - * Emitted when the mouse moves in the tray icon. - */ - on(event: 'mouse-move', listener: (event: Event, - /** - * The position of the event. - */ - position: Point) => void): this; - once(event: 'mouse-move', listener: (event: Event, - /** - * The position of the event. - */ - position: Point) => void): this; - addListener(event: 'mouse-move', listener: (event: Event, - /** - * The position of the event. - */ - position: Point) => void): this; - removeListener(event: 'mouse-move', listener: (event: Event, - /** - * The position of the event. + * The position of the event */ position: Point) => void): this; /** @@ -4486,22 +4039,22 @@ declare namespace Electron { */ on(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; once(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; addListener(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; removeListener(event: 'right-click', listener: (event: Event, /** - * The bounds of tray icon. + * The bounds of tray icon */ bounds: Rectangle) => void): this; constructor(image: NativeImage | string); @@ -4543,8 +4096,7 @@ declare namespace Electron { */ setPressedImage(image: NativeImage): void; /** - * Sets the title displayed aside of the tray icon in the status bar (Support ANSI - * colors). + * Sets the title displayed aside of the tray icon in the status bar. */ setTitle(title: string): void; /** @@ -4598,7 +4150,7 @@ declare namespace Electron { */ length: number; /** - * Last Modification time in number of seconds since the UNIX epoch. + * Last Modification time in number of seconds sine the UNIX epoch. */ modificationTime: number; /** @@ -4624,7 +4176,7 @@ declare namespace Electron { */ length: number; /** - * Last Modification time in number of seconds since the UNIX epoch. + * Last Modification time in number of seconds sine the UNIX epoch. */ modificationTime: number; /** @@ -4665,22 +4217,22 @@ declare namespace Electron { */ on(event: 'before-input-event', listener: (event: Event, /** - * Input properties. + * Input properties */ input: Input) => void): this; once(event: 'before-input-event', listener: (event: Event, /** - * Input properties. + * Input properties */ input: Input) => void): this; addListener(event: 'before-input-event', listener: (event: Event, /** - * Input properties. + * Input properties */ input: Input) => void): this; removeListener(event: 'before-input-event', listener: (event: Event, /** - * Input properties. + * Input properties */ input: Input) => void): this; /** @@ -4690,7 +4242,7 @@ declare namespace Electron { on(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code. + * The error code */ error: string, certificate: Certificate, @@ -4698,7 +4250,7 @@ declare namespace Electron { once(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code. + * The error code */ error: string, certificate: Certificate, @@ -4706,7 +4258,7 @@ declare namespace Electron { addListener(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code. + * The error code */ error: string, certificate: Certificate, @@ -4714,31 +4266,11 @@ declare namespace Electron { removeListener(event: 'certificate-error', listener: (event: Event, url: string, /** - * The error code. + * The error code */ error: string, certificate: Certificate, callback: (isTrusted: boolean) => void) => void): this; - /** - * Emitted when the associated window logs a console message. Will not be emitted - * for windows with offscreen rendering enabled. - */ - on(event: 'console-message', listener: (level: number, - message: string, - line: number, - sourceId: string) => void): this; - once(event: 'console-message', listener: (level: number, - message: string, - line: number, - sourceId: string) => void): this; - addListener(event: 'console-message', listener: (level: number, - message: string, - line: number, - sourceId: string) => void): this; - removeListener(event: 'console-message', listener: (level: number, - message: string, - line: number, - sourceId: string) => void): this; /** * Emitted when there is a new context menu that needs to be handled. */ @@ -4768,69 +4300,69 @@ declare namespace Electron { * nwse-resize, col-resize, row-resize, m-panning, e-panning, n-panning, * ne-panning, nw-panning, s-panning, se-panning, sw-panning, w-panning, move, * vertical-text, cell, context-menu, alias, progress, nodrop, copy, none, - * not-allowed, zoom-in, zoom-out, grab, grabbing or custom. If the type parameter - * is custom, the image parameter will hold the custom cursor image in a - * NativeImage, and scale, size and hotspot will hold additional information about - * the custom cursor. + * not-allowed, zoom-in, zoom-out, grab, grabbing, custom. If the type parameter is + * custom, the image parameter will hold the custom cursor image in a NativeImage, + * and scale, size and hotspot will hold additional information about the custom + * cursor. */ on(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor. + * scaling factor for the custom cursor */ scale?: number, /** - * the size of the `image`. + * the size of the `image` */ size?: Size, /** - * coordinates of the custom cursor's hotspot. + * coordinates of the custom cursor's hotspot */ hotspot?: Point) => void): this; once(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor. + * scaling factor for the custom cursor */ scale?: number, /** - * the size of the `image`. + * the size of the `image` */ size?: Size, /** - * coordinates of the custom cursor's hotspot. + * coordinates of the custom cursor's hotspot */ hotspot?: Point) => void): this; addListener(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor. + * scaling factor for the custom cursor */ scale?: number, /** - * the size of the `image`. + * the size of the `image` */ size?: Size, /** - * coordinates of the custom cursor's hotspot. + * coordinates of the custom cursor's hotspot */ hotspot?: Point) => void): this; removeListener(event: 'cursor-changed', listener: (event: Event, type: string, image?: NativeImage, /** - * scaling factor for the custom cursor. + * scaling factor for the custom cursor */ scale?: number, /** - * the size of the `image`. + * the size of the `image` */ size?: Size, /** - * coordinates of the custom cursor's hotspot. + * coordinates of the custom cursor's hotspot */ hotspot?: Point) => void): this; /** @@ -4868,53 +4400,14 @@ declare namespace Electron { once(event: 'devtools-reload-page', listener: Function): this; addListener(event: 'devtools-reload-page', listener: Function): this; removeListener(event: 'devtools-reload-page', listener: Function): this; - /** - * Emitted when a has been attached to this web contents. - */ - on(event: 'did-attach-webview', listener: (event: Event, - /** - * The guest web contents that is used by the ``. - */ - webContents: WebContents) => void): this; - once(event: 'did-attach-webview', listener: (event: Event, - /** - * The guest web contents that is used by the ``. - */ - webContents: WebContents) => void): this; - addListener(event: 'did-attach-webview', listener: (event: Event, - /** - * The guest web contents that is used by the ``. - */ - webContents: WebContents) => void): this; - removeListener(event: 'did-attach-webview', listener: (event: Event, - /** - * The guest web contents that is used by the ``. - */ - webContents: WebContents) => void): this; /** * Emitted when a page's theme color changes. This is usually due to encountering a * meta tag: */ - on(event: 'did-change-theme-color', listener: (event: Event, - /** - * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. - */ - color: string | null) => void): this; - once(event: 'did-change-theme-color', listener: (event: Event, - /** - * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. - */ - color: string | null) => void): this; - addListener(event: 'did-change-theme-color', listener: (event: Event, - /** - * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. - */ - color: string | null) => void): this; - removeListener(event: 'did-change-theme-color', listener: (event: Event, - /** - * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set. - */ - color: string | null) => void): this; + on(event: 'did-change-theme-color', listener: Function): this; + once(event: 'did-change-theme-color', listener: Function): this; + addListener(event: 'did-change-theme-color', listener: Function): this; + removeListener(event: 'did-change-theme-color', listener: Function): this; /** * This event is like did-finish-load but emitted when the load failed or was * cancelled, e.g. window.stop() is invoked. The full list of error codes and their @@ -5150,7 +4643,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new . + * The options which will be used for creating the new `BrowserWindow`. */ options: any, /** @@ -5167,7 +4660,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new . + * The options which will be used for creating the new `BrowserWindow`. */ options: any, /** @@ -5184,7 +4677,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new . + * The options which will be used for creating the new `BrowserWindow`. */ options: any, /** @@ -5201,7 +4694,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'), /** - * The options which will be used for creating the new . + * The options which will be used for creating the new `BrowserWindow`. */ options: any, /** @@ -5214,22 +4707,22 @@ declare namespace Electron { */ on(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs. + * Array of URLs */ favicons: string[]) => void): this; once(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs. + * Array of URLs */ favicons: string[]) => void): this; addListener(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs. + * Array of URLs */ favicons: string[]) => void): this; removeListener(event: 'page-favicon-updated', listener: (event: Event, /** - * Array of URLs. + * Array of URLs */ favicons: string[]) => void): this; /** @@ -5278,8 +4771,8 @@ declare namespace Electron { /** * Emitted when bluetooth device needs to be selected on call to * navigator.bluetooth.requestDevice. To use navigator.bluetooth api webBluetooth - * should be enabled. If event.preventDefault is not called, first available device - * will be selected. callback should be called with deviceId to be selected, + * should be enabled. If event.preventDefault is not called, first available + * device will be selected. callback should be called with deviceId to be selected, * passing empty string to callback will cancel the request. */ on(event: 'select-bluetooth-device', listener: (event: Event, @@ -5442,13 +4935,13 @@ declare namespace Electron { * called with callback(image). The image is an instance of NativeImage that stores * data of the snapshot. Omitting rect will capture the whole visible page. */ - capturePage(callback: (image: NativeImage) => void): void; + capturePage(rect: Rectangle, callback: (image: NativeImage) => void): void; /** * Captures a snapshot of the page within rect. Upon completion callback will be * called with callback(image). The image is an instance of NativeImage that stores * data of the snapshot. Omitting rect will capture the whole visible page. */ - capturePage(rect: Rectangle, callback: (image: NativeImage) => void): void; + capturePage(callback: (image: NativeImage) => void): void; /** * Clears the navigation history. */ @@ -5495,15 +4988,16 @@ declare namespace Electron { * requestFullScreen can only be invoked by a gesture from the user. Setting * userGesture to true will remove this limitation. If the result of the executed * code is a promise the callback result will be the resolved value of the promise. - * We recommend that you use the returned Promise to handle code that results in a + * We recommend that you use the returned Promise to handle code that results in a * Promise. */ executeJavaScript(code: string, userGesture?: boolean, callback?: (result: any) => void): Promise; /** - * Starts a request to find all matches for the text in the web page. The result of - * the request can be obtained by subscribing to found-in-page event. + * Starts a request to find all matches for the text in the web page and returns an + * Integer representing the request id used for the request. The result of the + * request can be obtained by subscribing to found-in-page event. */ - findInPage(text: string, options?: FindInPageOptions): number; + findInPage(text: string, options?: FindInPageOptions): void; /** * Focuses the web page. */ @@ -5582,12 +5076,6 @@ declare namespace Electron { isOffscreen(): boolean; isPainting(): boolean; isWaitingForResponse(): boolean; - /** - * Loads the given file in the window, filePath should be a path to an HTML file - * relative to the root of your application. For instance an app structure like - * this: Would require code like this - */ - loadFile(filePath: string): void; /** * Loads the url in the window. The url must contain the protocol prefix, e.g. the * http:// or file://. If the load should bypass http cache then use the pragma @@ -5595,9 +5083,7 @@ declare namespace Electron { */ loadURL(url: string, options?: LoadURLOptions): void; /** - * Opens the devtools. When contents is a tag, the mode would be detach - * by default, explicitly passing an empty mode can force using last used dock - * state. + * Opens the devtools. */ openDevTools(options?: OpenDevToolsOptions): void; /** @@ -5615,7 +5101,7 @@ declare namespace Electron { * webContents.print({silent: false, printBackground: false, deviceName: ''}). Use * page-break-before: always; CSS style to force to print to a new page. */ - print(options?: PrintOptions, callback?: (success: boolean) => void): void; + print(options?: PrintOptions): void; /** * Prints window's web page as PDF with Chromium's preview printing custom * settings. The callback will be called with callback(error, data) on completion. @@ -5674,19 +5160,6 @@ declare namespace Electron { * Mute the audio on the current web page. */ setAudioMuted(muted: boolean): void; - /** - * Uses the devToolsWebContents as the target WebContents to show devtools. The - * devToolsWebContents must not have done any navigation, and it should not be used - * for other purposes after the call. By default Electron manages the devtools by - * creating an internal WebContents with native view, which developers have very - * limited control of. With the setDevToolsWebContents method, developers can use - * any WebContents to show the devtools in it, including BrowserWindow, BrowserView - * and tag. Note that closing the devtools does not destroy the - * devToolsWebContents, it is caller's responsibility to destroy - * devToolsWebContents. An example of showing devtools in a tag: An - * example of showing devtools in a BrowserWindow: - */ - setDevToolsWebContents(devToolsWebContents: WebContents): void; /** * If offscreen rendering is enabled sets the frame rate to the specified number. * Only values between 1 and 60 are accepted. @@ -5714,7 +5187,7 @@ declare namespace Electron { setVisualZoomLevelLimits(minimumLevel: number, maximumLevel: number): void; /** * Setting the WebRTC IP handling policy allows you to control which IPs are - * exposed via WebRTC. See BrowserLeaks for more details. + * exposed via WebRTC. See BrowserLeaks for more details. */ setWebRTCIPHandlingPolicy(policy: 'default' | 'default_public_interface_only' | 'default_public_and_private_interfaces' | 'disable_non_proxied_udp'): void; /** @@ -5725,10 +5198,14 @@ declare namespace Electron { /** * Changes the zoom level to the specified level. The original size is 0 and each * increment above or below represents zooming 20% larger or smaller to default - * limits of 300% and 50% of original size, respectively. The formula for this is - * scale := 1.2 ^ level. + * limits of 300% and 50% of original size, respectively. */ setZoomLevel(level: number): void; + /** + * Deprecated: Call setVisualZoomLevelLimits instead to set the visual zoom level + * limits. This method will be removed in Electron 2.0. + */ + setZoomLevelLimits(minimumLevel: number, maximumLevel: number): void; /** * Shows pop-up dictionary that searches the selected word on the page. */ @@ -5799,10 +5276,6 @@ declare namespace Electron { * userGesture to true will remove this limitation. */ executeJavaScript(code: string, userGesture?: boolean, callback?: (result: any) => void): Promise; - /** - * Work like executeJavaScript but evaluates scripts in isolated context. - */ - executeJavaScriptInIsolatedWorld(worldId: number, scripts: WebSource[], userGesture?: boolean, callback?: (result: any) => void): void; /** * Returns an object describing usage information of Blink's internal memory * caches. This will generate: @@ -5832,18 +5305,6 @@ declare namespace Electron { * cannot be corrupted by active network attackers. */ registerURLSchemeAsSecure(scheme: string): void; - /** - * Set the content security policy of the isolated world. - */ - setIsolatedWorldContentSecurityPolicy(worldId: number, csp: string): void; - /** - * Set the name of the isolated world. Useful in devtools. - */ - setIsolatedWorldHumanReadableName(worldId: number, name: string): void; - /** - * Set the security origin of the isolated world. - */ - setIsolatedWorldSecurityOrigin(worldId: number, securityOrigin: string): void; /** * Sets the maximum and minimum layout-based (i.e. non-visual) zoom level. */ @@ -5869,28 +5330,22 @@ declare namespace Electron { * limits of 300% and 50% of original size, respectively. */ setZoomLevel(level: number): void; + /** + * Deprecated: Call setVisualZoomLevelLimits instead to set the visual zoom level + * limits. This method will be removed in Electron 2.0. + */ + setZoomLevelLimits(minimumLevel: number, maximumLevel: number): void; } class WebRequest extends EventEmitter { // Docs: http://electron.atom.io/docs/api/web-request - /** - * The listener will be called with listener(details) when a server initiated - * redirect is about to occur. - */ - onBeforeRedirect(listener: (details: OnBeforeRedirectDetails) => void): void; /** * The listener will be called with listener(details) when a server initiated * redirect is about to occur. */ onBeforeRedirect(filter: OnBeforeRedirectFilter, listener: (details: OnBeforeRedirectDetails) => void): void; - /** - * The listener will be called with listener(details, callback) when a request is - * about to occur. The uploadData is an array of UploadData objects. The callback - * has to be called with an response object. - */ - onBeforeRequest(listener: (details: OnBeforeRequestDetails, callback: (response: Response) => void) => void): void; /** * The listener will be called with listener(details, callback) when a request is * about to occur. The uploadData is an array of UploadData objects. The callback @@ -5904,25 +5359,10 @@ declare namespace Electron { * has to be called with an response object. */ onBeforeSendHeaders(filter: OnBeforeSendHeadersFilter, listener: Function): void; - /** - * The listener will be called with listener(details, callback) before sending an - * HTTP request, once the request headers are available. This may occur after a TCP - * connection is made to the server, but before any http data is sent. The callback - * has to be called with an response object. - */ - onBeforeSendHeaders(listener: Function): void; /** * The listener will be called with listener(details) when a request is completed. */ onCompleted(filter: OnCompletedFilter, listener: (details: OnCompletedDetails) => void): void; - /** - * The listener will be called with listener(details) when a request is completed. - */ - onCompleted(listener: (details: OnCompletedDetails) => void): void; - /** - * The listener will be called with listener(details) when an error occurs. - */ - onErrorOccurred(listener: (details: OnErrorOccurredDetails) => void): void; /** * The listener will be called with listener(details) when an error occurs. */ @@ -5933,18 +5373,6 @@ declare namespace Electron { * response object. */ onHeadersReceived(filter: OnHeadersReceivedFilter, listener: Function): void; - /** - * The listener will be called with listener(details, callback) when HTTP response - * headers of a request have been received. The callback has to be called with an - * response object. - */ - onHeadersReceived(listener: Function): void; - /** - * The listener will be called with listener(details) when first byte of the - * response body is received. For HTTP requests, this means that the status line - * and response headers are available. - */ - onResponseStarted(listener: (details: OnResponseStartedDetails) => void): void; /** * The listener will be called with listener(details) when first byte of the * response body is received. For HTTP requests, this means that the status line @@ -5957,24 +5385,6 @@ declare namespace Electron { * response are visible by the time this listener is fired. */ onSendHeaders(filter: OnSendHeadersFilter, listener: (details: OnSendHeadersDetails) => void): void; - /** - * The listener will be called with listener(details) just before a request is - * going to be sent to the server, modifications of previous onBeforeSendHeaders - * response are visible by the time this listener is fired. - */ - onSendHeaders(listener: (details: OnSendHeadersDetails) => void): void; - } - - interface WebSource { - - // Docs: http://electron.atom.io/docs/api/structures/web-source - - code: string; - /** - * Default is 1. - */ - startLine?: number; - url?: string; } interface WebviewTag extends HTMLElement { @@ -6165,10 +5575,6 @@ declare namespace Electron { */ addEventListener(event: 'devtools-focused', listener: (event: Event) => void, useCapture?: boolean): this; removeEventListener(event: 'devtools-focused', listener: (event: Event) => void): this; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; canGoBack(): boolean; canGoForward(): boolean; canGoToOffset(offset: number): boolean; @@ -6207,12 +5613,13 @@ declare namespace Electron { * context in the page. HTML APIs like requestFullScreen, which require user * action, can take advantage of this option for automation. */ - executeJavaScript(code: string, userGesture?: boolean, callback?: (result: any) => void): void; + executeJavaScript(code: string, userGesture: boolean, callback?: (result: any) => void): void; /** - * Starts a request to find all matches for the text in the web page. The result of - * the request can be obtained by subscribing to found-in-page event. + * Starts a request to find all matches for the text in the web page and returns an + * Integer representing the request id used for the request. The result of the + * request can be obtained by subscribing to found-in-page event. */ - findInPage(text: string, options?: FindInPageOptions): number; + findInPage(text: string, options?: FindInPageOptions): void; getTitle(): string; getURL(): string; getUserAgent(): string; @@ -6655,10 +6062,6 @@ declare namespace Electron { * is true. */ fullscreenable?: boolean; - /** - * Use pre-Lion fullscreen on macOS. Default is false. - */ - simpleFullscreen?: boolean; /** * Whether to show the window in taskbar. Default is false. */ @@ -6712,7 +6115,7 @@ declare namespace Electron { */ enableLargerThanScreen?: boolean; /** - * Window's background color as a hexadecimal value, like #66CD00 or #FFF or + * Window's background color as Hexadecimal value, like #66CD00 or #FFF or * #80FFFFFF (alpha is supported). Default is #FFF (white). */ backgroundColor?: string; @@ -6721,11 +6124,6 @@ declare namespace Electron { * is true. */ hasShadow?: boolean; - /** - * Set the initial opacity of the window, between 0.0 (fully transparent) and 1.0 - * (fully opaque). This is only implemented on Windows and macOS. - */ - opacity?: number; /** * Forces using dark theme for the window, only works on some GTK+3 desktop * environments. Default is false. @@ -6742,9 +6140,9 @@ declare namespace Electron { /** * The style of window title bar. Default is default. Possible values are: */ - titleBarStyle?: ('default' | 'hidden' | 'hiddenInset' | 'customButtonsOnHover'); + titleBarStyle?: ('default' | 'hidden' | 'hidden-inset' | 'hiddenInset' | 'customButtonsOnHover'); /** - * Shows the title in the title bar in full screen mode on macOS for all + * Shows the title in the tile bar in full screen mode on macOS for all * titleBarStyle options. Default is false. */ fullscreenWindowTitle?: boolean; @@ -6798,11 +6196,7 @@ declare namespace Electron { /** * Verification result from chromium. */ - verificationResult: string; - /** - * Error code. - */ - errorCode: number; + error: string; } interface ClearStorageDataOptions { @@ -6812,7 +6206,7 @@ declare namespace Electron { origin?: string; /** * The types of storages to clear, can contain: appcache, cookies, filesystem, - * indexdb, localstorage, shadercache, websql, serviceworkers. + * indexdb, localstorage, shadercache, websql, serviceworkers */ storages?: string[]; /** @@ -6859,11 +6253,11 @@ declare namespace Electron { interface ContextMenuParams { /** - * x coordinate. + * x coordinate */ x: number; /** - * y coordinate. + * y coordinate */ y: number; /** @@ -6923,8 +6317,8 @@ declare namespace Electron { */ inputFieldType: string; /** - * Input source that invoked the context menu. Can be none, mouse, keyboard, touch - * or touchMenu. + * Input source that invoked the context menu. Can be none, mouse, keyboard, touch, + * touchMenu. */ menuSourceType: ('none' | 'mouse' | 'keyboard' | 'touch' | 'touchMenu'); /** @@ -6961,10 +6355,9 @@ declare namespace Electron { * properties are sent correctly. Nested objects are not supported and the property * names and values must be less than 64 characters long. */ - extra?: Extra; + extra?: any; /** - * Directory to store the crashreports temporarily (only used when the crash - * reporter is started via process.crashReporter.start). + * Only used when the crash reporter is used in a forked process (macOS only). */ crashesDirectory?: string; } @@ -7109,12 +6502,9 @@ declare namespace Electron { } interface DisplayBalloonOptions { - /** - * - - */ icon?: NativeImage | string; - title: string; - content: string; + title?: string; + content?: string; } interface Dock { @@ -7179,18 +6569,6 @@ declare namespace Electron { interface Extensions { } - interface FeedURLOptions { - url: string; - /** - * HTTP request headers. - */ - headers?: Headers; - /** - * Either json or default, see the README for more information. - */ - serverType?: string; - } - interface FileIconOptions { size: ('small' | 'normal' | 'large'); } @@ -7206,7 +6584,7 @@ declare namespace Electron { */ name?: string; /** - * Retrieves cookies whose domains match or are subdomains of domains. + * Retrieves cookies whose domains match or are subdomains of domains */ domain?: string; /** @@ -7266,18 +6644,6 @@ declare namespace Electron { name: string; } - interface Headers { - } - - interface IgnoreMouseEventsOptions { - /** - * If true, forwards mouse move messages to Chromium, enabling mouse related events - * such as mouseleave. Only used when ignore is true. If ignore is false, - * forwarding is always disabled regardless of this value. - */ - forward?: boolean; - } - interface ImportCertificateOptions { /** * Path for the pkcs12 file. @@ -7291,35 +6657,35 @@ declare namespace Electron { interface Input { /** - * Either keyUp or keyDown. + * Either keyUp or keyDown */ type: string; /** - * Equivalent to . + * Equivalent to */ key: string; /** - * Equivalent to . + * Equivalent to */ code: string; /** - * Equivalent to . + * Equivalent to */ isAutoRepeat: boolean; /** - * Equivalent to . + * Equivalent to */ shift: boolean; /** - * Equivalent to . + * Equivalent to */ control: boolean; /** - * Equivalent to . + * Equivalent to */ alt: boolean; /** - * Equivalent to . + * Equivalent to */ meta: boolean; } @@ -7345,14 +6711,6 @@ declare namespace Electron { uploadData: UploadData[]; } - interface InterceptStreamProtocolRequest { - url: string; - headers: Headers; - referrer: string; - method: string; - uploadData: UploadData[]; - } - interface InterceptStringProtocolRequest { url: string; referrer: string; @@ -7409,9 +6767,6 @@ declare namespace Electron { * Extra headers separated by "\n" */ extraHeaders?: string; - /** - * - - */ postData?: UploadRawData[] | UploadFile[] | UploadFileSystem[] | UploadBlob[]; /** * Base url (with trailing path separator) for files to be loaded by the data url. @@ -7428,25 +6783,25 @@ declare namespace Electron { */ openAtLogin: boolean; /** - * true if the app is set to open as hidden at login. This setting is not available - * on . + * true if the app is set to open as hidden at login. This setting is only + * supported on macOS. */ openAsHidden: boolean; /** - * true if the app was opened at login automatically. This setting is not available - * on . + * true if the app was opened at login automatically. This setting is only + * supported on macOS. */ wasOpenedAtLogin: boolean; /** * true if the app was opened as a hidden login item. This indicates that the app - * should not open any windows at startup. This setting is not available on . + * should not open any windows at startup. This setting is only supported on macOS. */ wasOpenedAsHidden: boolean; /** * true if the app was opened as a login item that should restore the state from * the previous session. This indicates that the app should restore the windows - * that were open the last time the app was closed. This setting is not available - * on . + * that were open the last time the app was closed. This setting is only supported + * on macOS. */ restoreState: boolean; } @@ -7472,7 +6827,7 @@ declare namespace Electron { * Define the action of the menu item, when specified the click property will be * ignored. See . */ - role?: string; + role?: MenuItemRole; /** * Can be normal, separator, submenu, checkbox or radio. */ @@ -7495,7 +6850,7 @@ declare namespace Electron { checked?: boolean; /** * Should be specified for submenu type menu items. If submenu is specified, the - * type: 'submenu' can be omitted. If the value is not a then it will be + * type: 'submenu' can be omitted. If the value is not a Menu then it will be * automatically converted to one using Menu.buildFromTemplate. */ submenu?: MenuItemConstructorOptions[] | Menu; @@ -7585,7 +6940,7 @@ declare namespace Electron { */ disposition: ('default' | 'foreground-tab' | 'background-tab' | 'new-window' | 'save-to-disk' | 'other'); /** - * The options which should be used for creating the new . + * The options which should be used for creating the new `BrowserWindow`. */ options: Options; } @@ -7593,7 +6948,7 @@ declare namespace Electron { interface NotificationConstructorOptions { /** * A title for the notification, which will be shown at the top of the notification - * window when it is shown. + * window when it is shown */ title: string; /** @@ -7602,17 +6957,17 @@ declare namespace Electron { subtitle?: string; /** * The body text of the notification, which will be displayed below the title or - * subtitle. + * subtitle */ body: string; /** - * Whether or not to emit an OS notification noise when showing the notification. + * Whether or not to emit an OS notification noise when showing the notification */ silent?: boolean; /** - * An icon to use in the notification. + * An icon to use in the notification */ - icon?: string | NativeImage; + icon?: NativeImage; /** * Whether or not to add an inline reply option to the notification. */ @@ -7627,21 +6982,15 @@ declare namespace Electron { sound?: string; /** * Actions to add to the notification. Please read the available actions and - * limitations in the NotificationAction documentation. + * limitations in the NotificationAction documentation */ actions?: NotificationAction[]; - /** - * A custom title for the close button of an alert. An empty string will cause the - * default localized text to be used. - */ - closeButtonText?: string; } interface OnBeforeRedirectDetails { - id: number; + id: string; url: string; method: string; - webContentsId?: number; resourceType: string; timestamp: number; redirectURL: string; @@ -7666,7 +7015,6 @@ declare namespace Electron { id: number; url: string; method: string; - webContentsId?: number; resourceType: string; timestamp: number; uploadData: UploadData[]; @@ -7692,7 +7040,6 @@ declare namespace Electron { id: number; url: string; method: string; - webContentsId?: number; resourceType: string; timestamp: number; responseHeaders: ResponseHeaders; @@ -7713,7 +7060,6 @@ declare namespace Electron { id: number; url: string; method: string; - webContentsId?: number; resourceType: string; timestamp: number; fromCache: boolean; @@ -7743,7 +7089,6 @@ declare namespace Electron { id: number; url: string; method: string; - webContentsId?: number; resourceType: string; timestamp: number; responseHeaders: ResponseHeaders; @@ -7767,7 +7112,6 @@ declare namespace Electron { id: number; url: string; method: string; - webContentsId?: number; resourceType: string; timestamp: number; requestHeaders: RequestHeaders; @@ -7808,10 +7152,6 @@ declare namespace Electron { * Message to display above input boxes. */ message?: string; - /** - * Create when packaged for the Mac App Store. - */ - securityScopedBookmarks?: boolean; } interface OpenExternalOptions { @@ -7835,56 +7175,50 @@ declare namespace Electron { interface Parameters { /** - * Specify the screen type to emulate (default: desktop): + * Specify the screen type to emulate (default: desktop) */ screenPosition: ('desktop' | 'mobile'); /** - * Set the emulated screen size (screenPosition == mobile). + * Set the emulated screen size (screenPosition == mobile) */ screenSize: Size; /** * Position the view on the screen (screenPosition == mobile) (default: {x: 0, y: - * 0}). + * 0}) */ viewPosition: Point; /** * Set the device scale factor (if zero defaults to original device scale factor) - * (default: 0). + * (default: 0) */ deviceScaleFactor: number; /** * Set the emulated view size (empty means no override) */ viewSize: Size; + /** + * Whether emulated view should be scaled down if necessary to fit into available + * space (default: false) + */ + fitToView: boolean; + /** + * Offset of the emulated view inside available space (not in fit to view mode) + * (default: {x: 0, y: 0}) + */ + offset: Point; /** * Scale of emulated view inside available space (not in fit to view mode) - * (default: 1). + * (default: 1) */ scale: number; } - interface Payment { - productIdentifier: string; - quantity: number; - } - - interface PermissionRequestHandlerDetails { - /** - * The url of the openExternal request. - */ - externalURL: string; - } - interface PluginCrashedEvent extends Event { name: string; version: string; } interface PopupOptions { - /** - * Default is the focused window. - */ - window?: BrowserWindow; /** * Default is the current mouse cursor position. Must be declared if y is declared. */ @@ -7893,15 +7227,16 @@ declare namespace Electron { * Default is the current mouse cursor position. Must be declared if x is declared. */ y?: number; + /** + * Set to true to have this method return immediately called, false to return after + * the menu has been selected or closed. Defaults to false. + */ + async?: boolean; /** * The index of the menu item to be positioned under the mouse cursor at the * specified coordinates. Default is -1. */ positioningItem?: number; - /** - * Called when menu is closed. - */ - callback?: () => void; } interface PrintOptions { @@ -7960,7 +7295,7 @@ declare namespace Electron { privateBytes: number; /** * The amount of memory shared between processes, typically memory consumed by the - * Electron code itself. + * Electron code itself */ sharedBytes: number; } @@ -7974,7 +7309,7 @@ declare namespace Electron { interface Provider { /** - * Returns Boolean. + * Returns Boolean */ spellCheck: (text: string) => void; } @@ -8019,14 +7354,6 @@ declare namespace Electron { secure?: boolean; } - interface RegisterStreamProtocolRequest { - url: string; - headers: Headers; - referrer: string; - method: string; - uploadData: UploadData[]; - } - interface RegisterStringProtocolRequest { url: string; referrer: string; @@ -8074,7 +7401,7 @@ declare namespace Electron { */ width?: number; /** - * Defaults to the image's height. + * Defaults to the image's height */ height?: number; /** @@ -8145,11 +7472,6 @@ declare namespace Electron { * Show the tags input box, defaults to true. */ showsTagField?: boolean; - /** - * Create a when packaged for the Mac App Store. If this option is enabled and the - * file doesn't already exist a blank file will be created at the chosen path. - */ - securityScopedBookmarks?: boolean; } interface Settings { @@ -8162,7 +7484,7 @@ declare namespace Electron { * true to open the app as hidden. Defaults to false. The user can edit this * setting from the System Preferences so * app.getLoginItemStatus().wasOpenedAsHidden should be checked when the app is - * opened to know the current value. This setting is not available on . + * opened to know the current value. This setting is only supported on macOS. */ openAsHidden?: boolean; /** @@ -8263,7 +7585,7 @@ declare namespace Electron { /** * Can be left, right or overlay. */ - iconPosition?: ('left' | 'right' | 'overlay'); + iconPosition: ('left' | 'right' | 'overlay'); /** * Function to call when the button is clicked. */ @@ -8286,8 +7608,8 @@ declare namespace Electron { } interface TouchBarConstructorOptions { - items: Array; - escapeItem?: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer | null; + items: (TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer)[]; + escapeItem?: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer; } interface TouchBarGroupConstructorOptions { @@ -8330,15 +7652,15 @@ declare namespace Electron { interface TouchBarScrubberConstructorOptions { /** - * An array of items to place in this scrubber. + * An array of items to place in this scrubber */ items: ScrubberItem[]; /** - * Called when the user taps an item that was not the last tapped item. + * Called when the user taps an item that was not the last tapped item */ select: (selectedIndex: number) => void; /** - * Called when the user taps any item. + * Called when the user taps any item */ highlight: (highlightedIndex: number) => void; /** @@ -8382,7 +7704,7 @@ declare namespace Electron { */ selectedIndex?: number; /** - * Called when the user selects a new segment. + * Called when the user selects a new segment */ change: (selectedIndex: number, isSelected: boolean) => void; } @@ -8487,6 +7809,9 @@ declare namespace Electron { finalUpdate: boolean; } + interface Headers { + } + interface MediaFlags { /** * Whether the media element has crashed. @@ -8586,15 +7911,6 @@ declare namespace Electron { * session. */ partition?: string; - /** - * When specified, web pages with the same affinity will run in the same renderer - * process. Note that due to reusing the renderer process, certain webPreferences - * options will also be shared between the web pages even when you specified - * different values for them, including but not limited to preload, sandbox and - * nodeIntegration. So it is suggested to use exact same webPreferences for web - * pages with the same affinity. - */ - affinity?: string; /** * The default zoom factor of the page, 3.0 represents 300%. Default is 1.0. */ @@ -8678,7 +7994,7 @@ declare namespace Electron { defaultEncoding?: string; /** * Whether to throttle animations and timers when the page becomes background. This - * also affects the . Defaults to true. + * also affects the [Page Visibility API][#page-visibility]. Defaults to true. */ backgroundThrottling?: boolean; /** @@ -8715,12 +8031,6 @@ declare namespace Electron { * alter the 's initial settings. */ webviewTag?: boolean; - /** - * A list of strings that will be appended to process.argv in the renderer process - * of this app. Useful for passing small bits of data down to renderer process - * preload scripts. - */ - additionArguments?: string[]; } interface DefaultFontFamily { @@ -8798,7 +8108,6 @@ declare namespace NodeJS { // Docs: http://electron.atom.io/docs/api/process - // ### BEGIN VSCODE MODIFICATION ### // /** // * Emitted when Electron has loaded its internal initialization script and is // * beginning to load the web page or the main script. It can be used by the preload @@ -8809,8 +8118,6 @@ declare namespace NodeJS { // once(event: 'loaded', listener: Function): this; // addListener(event: 'loaded', listener: Function): this; // removeListener(event: 'loaded', listener: Function): this; - // ### END VSCODE MODIFICATION ### - /** * Causes the main thread of the current process crash. */ @@ -8853,8 +8160,8 @@ declare namespace NodeJS { noAsar?: boolean; /** * A Boolean that controls whether or not deprecation warnings are printed to - * stderr. Setting this to true will silence deprecation warnings. This property is - * used instead of the --no-deprecation command line flag. + * stderr. Setting this to true will silence deprecation warnings. This property + * is used instead of the --no-deprecation command line flag. */ noDeprecation?: boolean; /** @@ -8863,21 +8170,21 @@ declare namespace NodeJS { resourcesPath?: string; /** * A Boolean that controls whether or not deprecation warnings will be thrown as - * exceptions. Setting this to true will throw errors for deprecations. This + * exceptions. Setting this to true will throw errors for deprecations. This * property is used instead of the --throw-deprecation command line flag. */ throwDeprecation?: boolean; /** * A Boolean that controls whether or not deprecations printed to stderr include - * their stack trace. Setting this to true will print stack traces for + * their stack trace. Setting this to true will print stack traces for * deprecations. This property is instead of the --trace-deprecation command line * flag. */ traceDeprecation?: boolean; /** * A Boolean that controls whether or not process warnings printed to stderr - * include their stack trace. Setting this to true will print stack traces for - * process warnings (including deprecations). This property is instead of the + * include their stack trace. Setting this to true will print stack traces for + * process warnings (including deprecations). This property is instead of the * --trace-warnings command line flag. */ traceProcessWarnings?: boolean; @@ -8896,4 +8203,4 @@ declare namespace NodeJS { electron: string; chrome: string; } -} +} \ No newline at end of file diff --git a/src/typings/node-pty.d.ts b/src/typings/node-pty.d.ts index e09b1eb47e5..e3ee561a60c 100644 --- a/src/typings/node-pty.d.ts +++ b/src/typings/node-pty.d.ts @@ -1,27 +1,81 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ +/** + * Copyright (c) 2017, Daniel Imms (MIT License). + */ declare module 'node-pty' { - export function fork(file: string, args: string[], options: any): Terminal; - export function spawn(file: string, args: string[], options: any): Terminal; - export function createTerminal(file: string, args: string[], options: any): Terminal; + /** + * Forks a process as a pseudoterminal. + * @param file The file to launch. + * @param args The file's arguments as argv (string[]) or in a pre-escaped CommandLine format + * (string). Note that the CommandLine option is only available on Windows and is expected to be + * escaped properly. + * @param options The options of the terminal. + * @see CommandLineToArgvW https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx + * @see Parsing C++ Comamnd-Line Arguments https://msdn.microsoft.com/en-us/library/17w5ykft.aspx + * @see GetCommandLine https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156.aspx + */ + export function spawn(file: string, args: string[] | string, options: IPtyForkOptions): IPty; - export interface Terminal { - pid: number; - - /** - * The title of the active process. - */ - process: string; - - on(event: string, callback: (data: any) => void): void; - - resize(columns: number, rows: number): void; - - write(data: string): void; - - kill(): void; + export interface IPtyForkOptions { + name?: string; + cols?: number; + rows?: number; + cwd?: string; + env?: { [key: string]: string }; + uid?: number; + gid?: number; + encoding?: string; } -} \ No newline at end of file + + /** + * An interface representing a pseudoterminal, on Windows this is emulated via the winpty library. + */ + export interface IPty { + /** + * The process ID of the outer process. + */ + pid: number; + + /** + * The title of the active process. + */ + process: string; + + /** + * Adds a listener to the data event, fired when data is returned from the pty. + * @param event The name of the event. + * @param listener The callback function. + */ + on(event: 'data', listener: (data: string) => void): void; + + /** + * Adds a listener to the exit event, fired when the pty exits. + * @param event The name of the event. + * @param listener The callback function, exitCode is the exit code of the process and signal is + * the signal that triggered the exit. signal is not supported on Windows. + */ + on(event: 'exit', listener: (exitCode: number, signal?: number) => void): void; + + /** + * Resizes the dimensions of the pty. + * @param columns THe number of columns to use. + * @param rows The number of rows to use. + */ + resize(columns: number, rows: number): void; + + /** + * Writes data to the pty. + * @param data The data to write. + */ + write(data: string): void; + + /** + * Kills the pty. + * @param signal The signal to use, defaults to SIGHUP. If the TIOCSIG/TIOCSIGNAL ioctl is not + * supported then the process will be killed instead. This parameter is not supported on + * Windows. + * @throws Will throw when signal is used on Windows. + */ + kill(signal?: string): void; + } + } \ No newline at end of file diff --git a/src/typings/node.d.ts b/src/typings/node.d.ts index a1c8edf9d48..1b6661edd71 100644 --- a/src/typings/node.d.ts +++ b/src/typings/node.d.ts @@ -1,62 +1,41 @@ -// Type definitions for Node.js 8.9.x +// Type definitions for Node.js v7.x // Project: http://nodejs.org/ // Definitions by: Microsoft TypeScript // DefinitelyTyped // Parambir Singh +// Roberto Desideri // Christian Vaagland Tellnes // Wilco Bakker -// Nicolas Voigt -// Chigozirim C. -// Flarna -// Mariusz Wiktorczyk -// wwwy3y3 -// Deividas Bakanas -// Kelvin Jin -// Alvis HT Tang -// Oliver Joseph Ash -// Sebastian Silbermann -// Hannes Magnusson -// Alberto Schiabel -// Huw +// Daniel Imms // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.1 -// ### BEGIN VSCODE MODIFICATION ### -// /** inspector module types */ -// /// -// ### BEGIN VSCODE MODIFICATION ### +/************************************************ +* * +* Node.js v7.x API * +* * +************************************************/ // This needs to be global to avoid TS2403 in case lib.dom.d.ts is present in the same build interface Console { - Console: NodeJS.ConsoleConstructor; - assert(value: any, message?: string, ...optionalParams: any[]): void; - dir(obj: any, options?: NodeJS.InspectOptions): void; - error(message?: any, ...optionalParams: any[]): void; - info(message?: any, ...optionalParams: any[]): void; - log(message?: any, ...optionalParams: any[]): void; - time(label: string): void; - timeEnd(label: string): void; - trace(message?: any, ...optionalParams: any[]): void; - warn(message?: any, ...optionalParams: any[]): void; + Console: NodeJS.ConsoleConstructor; + assert(value: any, message?: string, ...optionalParams: any[]): void; + dir(obj: any, options?: NodeJS.InspectOptions): void; + error(message?: any, ...optionalParams: any[]): void; + info(message?: any, ...optionalParams: any[]): void; + log(message?: any, ...optionalParams: any[]): void; + time(label: string): void; + timeEnd(label: string): void; + trace(message?: any, ...optionalParams: any[]): void; + warn(message?: any, ...optionalParams: any[]): void; } interface Error { - stack?: string; + stack?: string; } -// Declare "static" methods in Error interface ErrorConstructor { - /** Create .stack property on a target object */ - captureStackTrace(targetObject: Object, constructorOpt?: Function): void; - - /** - * Optional override for formatting stack traces - * - * @see https://github.com/v8/v8/wiki/Stack%20Trace%20API#customizing-stack-traces - */ - prepareStackTrace?: (err: Error, stackTraces: NodeJS.CallSite[]) => any; - - stackTraceLimit: number; + captureStackTrace(targetObject: Object, constructorOpt?: Function): void; + stackTraceLimit: number; } // compat for TypeScript 1.8 @@ -70,85 +49,55 @@ interface WeakSetConstructor { } // Forward-declare needed types from lib.es2015.d.ts (in case users are using `--lib es5`) interface Iterable { } interface Iterator { - next(value?: any): IteratorResult; + next(value?: any): IteratorResult; } interface IteratorResult { } interface SymbolConstructor { - readonly iterator: symbol; + readonly iterator: symbol; } declare var Symbol: SymbolConstructor; -// Node.js ESNEXT support -interface String { - /** Removes whitespace from the left end of a string. */ - trimLeft(): string; - /** Removes whitespace from the right end of a string. */ - trimRight(): string; -} - /************************************************ * * * GLOBAL * * * ************************************************/ declare var process: NodeJS.Process; -declare var global: NodeJS.Global; +declare var global: any; declare var console: Console; -// ### BEGIN VSCODE MODIFICATION ### +// Don't use these!! :) // declare var __filename: string; // declare var __dirname: string; // declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -// declare namespace setTimeout { -// export function __promisify__(ms: number): Promise; -// export function __promisify__(ms: number, value: T): Promise; -// } // declare function clearTimeout(timeoutId: NodeJS.Timer): void; // declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; // declare function clearInterval(intervalId: NodeJS.Timer): void; -// ### END VSCODE MODIFICATION ### - declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; -declare namespace setImmediate { - export function __promisify__(): Promise; - export function __promisify__(value: T): Promise; -} declare function clearImmediate(immediateId: any): void; -// TODO: change to `type NodeRequireFunction = (id: string) => any;` in next mayor version. interface NodeRequireFunction { - /* tslint:disable-next-line:callable-types */ - (id: string): any; + (id: string): any; } -// ### BEGIN VSCODE MODIFICATION ### // interface NodeRequire extends NodeRequireFunction { // resolve(id: string): string; // cache: any; -// extensions: NodeExtensions; +// extensions: any; // main: NodeModule | undefined; // } -// interface NodeExtensions { -// '.js': (m: NodeModule, filename: string) => any; -// '.json': (m: NodeModule, filename: string) => any; -// '.node': (m: NodeModule, filename: string) => any; -// [ext: string]: (m: NodeModule, filename: string) => any; -// } - // declare var require: NodeRequire; -// ### END VSCODE MODIFICATION ### interface NodeModule { - exports: any; - require: NodeRequireFunction; - id: string; - filename: string; - loaded: boolean; - parent: NodeModule | null; - children: NodeModule[]; - paths: string[]; + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: NodeModule | null; + children: NodeModule[]; } declare var module: NodeModule; @@ -156,16 +105,17 @@ declare var module: NodeModule; // Same as module.exports declare var exports: any; declare var SlowBuffer: { - new(str: string, encoding?: string): Buffer; - new(size: number): Buffer; - new(size: Uint8Array): Buffer; - new(array: any[]): Buffer; - prototype: Buffer; - isBuffer(obj: any): boolean; - byteLength(string: string, encoding?: string): number; - concat(list: Buffer[], totalLength?: number): Buffer; + new(str: string, encoding?: string): Buffer; + new(size: number): Buffer; + new(size: Uint8Array): Buffer; + new(array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; }; + // Buffer class type BufferEncoding = "ascii" | "utf8" | "utf16le" | "ucs2" | "base64" | "latin1" | "binary" | "hex"; interface Buffer extends NodeBuffer { } @@ -182,19 +132,19 @@ declare var Buffer: { * @param str String to store in buffer. * @param encoding encoding to use, optional. Default is 'utf8' */ - new(str: string, encoding?: string): Buffer; + new(str: string, encoding?: string): Buffer; /** * Allocates a new buffer of {size} octets. * * @param size count of octets to allocate. */ - new(size: number): Buffer; + new(size: number): Buffer; /** * Allocates a new buffer containing the given {array} of octets. * * @param array The octets to store. */ - new(array: Uint8Array): Buffer; + new(array: Uint8Array): Buffer; /** * Produces a Buffer backed by the same allocated memory as * the given {ArrayBuffer}. @@ -202,24 +152,26 @@ declare var Buffer: { * * @param arrayBuffer The ArrayBuffer with which to share memory. */ - new(arrayBuffer: ArrayBuffer): Buffer; + new(arrayBuffer: ArrayBuffer): Buffer; /** * Allocates a new buffer containing the given {array} of octets. * * @param array The octets to store. */ - new(array: any[]): Buffer; + new(array: any[]): Buffer; /** * Copies the passed {buffer} data onto a new {Buffer} instance. * * @param buffer The buffer to copy. */ - new(buffer: Buffer): Buffer; - prototype: Buffer; + new(buffer: Buffer): Buffer; + prototype: Buffer; /** * Allocates a new Buffer using an {array} of octets. + * + * @param array */ - from(array: any[]): Buffer; + from(array: any[]): Buffer; /** * When passed a reference to the .buffer property of a TypedArray instance, * the newly created Buffer will share the same allocated memory as the TypedArray. @@ -227,39 +179,45 @@ declare var Buffer: { * within the {arrayBuffer} that will be shared by the Buffer. * * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() + * @param byteOffset + * @param length */ - from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; /** * Copies the passed {buffer} data onto a new Buffer instance. + * + * @param buffer */ - from(buffer: Buffer): Buffer; + from(buffer: Buffer): Buffer; /** * Creates a new Buffer containing the given JavaScript string {str}. * If provided, the {encoding} parameter identifies the character encoding. * If not provided, {encoding} defaults to 'utf8'. + * + * @param str */ - from(str: string, encoding?: string): Buffer; + from(str: string, encoding?: string): Buffer; /** * Returns true if {obj} is a Buffer * * @param obj object to test. */ - isBuffer(obj: any): obj is Buffer; + isBuffer(obj: any): obj is Buffer; /** * Returns true if {encoding} is a valid encoding argument. * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' * * @param encoding string to test. */ - isEncoding(encoding: string): boolean; + isEncoding(encoding: string): boolean; /** * Gives the actual byte length of a string. encoding defaults to 'utf8'. * This is not the same as String.prototype.length since that returns the number of characters in a string. * - * @param string string to test. (TypedArray is also allowed, but it is only available starting ES2017) + * @param string string to test. * @param encoding encoding used to evaluate (defaults to 'utf8') */ - byteLength(string: string | Buffer | DataView | ArrayBuffer, encoding?: string): number; + byteLength(string: string, encoding?: string): number; /** * Returns a buffer which is the result of concatenating all the buffers in the list together. * @@ -271,11 +229,11 @@ declare var Buffer: { * @param totalLength Total length of the buffers when concatenated. * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. */ - concat(list: Buffer[], totalLength?: number): Buffer; + concat(list: Buffer[], totalLength?: number): Buffer; /** * The same as buf1.compare(buf2). */ - compare(buf1: Buffer, buf2: Buffer): number; + compare(buf1: Buffer, buf2: Buffer): number; /** * Allocates a new buffer of {size} octets. * @@ -284,25 +242,21 @@ declare var Buffer: { * If parameter is omitted, buffer will be filled with zeros. * @param encoding encoding used for call to buf.fill while initalizing */ - alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; + alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; /** * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents * of the newly created Buffer are unknown and may contain sensitive data. * * @param size count of octets to allocate */ - allocUnsafe(size: number): Buffer; + allocUnsafe(size: number): Buffer; /** * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents * of the newly created Buffer are unknown and may contain sensitive data. * * @param size count of octets to allocate */ - allocUnsafeSlow(size: number): Buffer; - /** - * This is the number of bytes used to determine the size of pre-allocated, internal Buffer instances used for pooling. This value may be modified. - */ - poolSize: number; + allocUnsafeSlow(size: number): Buffer; }; /************************************************ @@ -311,501 +265,273 @@ declare var Buffer: { * * ************************************************/ declare namespace NodeJS { - export interface InspectOptions { - showHidden?: boolean; - depth?: number | null; - colors?: boolean; - customInspect?: boolean; - showProxy?: boolean; - maxArrayLength?: number | null; - breakLength?: number; - } + export interface InspectOptions { + showHidden?: boolean; + depth?: number | null; + colors?: boolean; + customInspect?: boolean; + showProxy?: boolean; + maxArrayLength?: number | null; + breakLength?: number; + } - export interface ConsoleConstructor { - prototype: Console; - new(stdout: WritableStream, stderr?: WritableStream): Console; - } + export interface ConsoleConstructor { + prototype: Console; + new(stdout: WritableStream, stderr?: WritableStream): Console; + } - export interface CallSite { - /** - * Value of "this" - */ - getThis(): any; + export interface ErrnoException extends Error { + errno?: number; + code?: string; + path?: string; + syscall?: string; + stack?: string; + } - /** - * Type of "this" as a string. - * This is the name of the function stored in the constructor field of - * "this", if available. Otherwise the object's [[Class]] internal - * property. - */ - getTypeName(): string | null; + export class EventEmitter { + addListener(event: string | symbol, listener: Function): this; + on(event: string | symbol, listener: Function): this; + once(event: string | symbol, listener: Function): this; + removeListener(event: string | symbol, listener: Function): this; + removeAllListeners(event?: string | symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string | symbol): Function[]; + emit(event: string | symbol, ...args: any[]): boolean; + listenerCount(type: string | symbol): number; + // Added in Node 6... + prependListener(event: string | symbol, listener: Function): this; + prependOnceListener(event: string | symbol, listener: Function): this; + eventNames(): (string | symbol)[]; + } - /** - * Current function - */ - getFunction(): Function | undefined; + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string | Buffer; + setEncoding(encoding: string | null): this; + pause(): this; + resume(): this; + isPaused(): boolean; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): this; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } - /** - * Name of the current function, typically its name property. - * If a name property is not available an attempt will be made to try - * to infer a name from the function's context. - */ - getFunctionName(): string | null; + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer | string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } - /** - * Name of the property [of "this" or one of its prototypes] that holds - * the current function - */ - getMethodName(): string | null; + export interface ReadWriteStream extends ReadableStream, WritableStream { } - /** - * Name of the script [if this function was defined in a script] - */ - getFileName(): string | null; + export interface Events extends EventEmitter { } - /** - * Current line number [if this function was defined in a script] - */ - getLineNumber(): number | null; + export interface Domain extends Events { + run(fn: Function): void; + add(emitter: Events): void; + remove(emitter: Events): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; - /** - * Current column number [if this function was defined in a script] - */ - getColumnNumber(): number | null; + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + } - /** - * A call site object representing the location where eval was called - * [if this function was created using a call to eval] - */ - getEvalOrigin(): string | undefined; + export interface MemoryUsage { + rss: number; + heapTotal: number; + heapUsed: number; + } - /** - * Is this a toplevel invocation, that is, is "this" the global object? - */ - isToplevel(): boolean; + export interface CpuUsage { + user: number; + system: number; + } - /** - * Does this call take place in code defined by a call to eval? - */ - isEval(): boolean; + export interface ProcessVersions { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + modules: string; + openssl: string; + } - /** - * Is this call in native V8 code? - */ - isNative(): boolean; + type Platform = 'aix' + | 'android' + | 'darwin' + | 'freebsd' + | 'linux' + | 'openbsd' + | 'sunos' + | 'win32'; - /** - * Is this a constructor call? - */ - isConstructor(): boolean; - } + export interface Socket extends ReadWriteStream { + isTTY?: true; + } - export interface ErrnoException extends Error { - errno?: number; - code?: string; - path?: string; - syscall?: string; - stack?: string; - } + export interface WriteStream extends Socket { + columns?: number; + rows?: number; + } + export interface ReadStream extends Socket { + isRaw?: boolean; + setRawMode?(mode: boolean): void; + } - export class EventEmitter { - addListener(event: string | symbol, listener: (...args: any[]) => void): this; - on(event: string | symbol, listener: (...args: any[]) => void): this; - once(event: string | symbol, listener: (...args: any[]) => void): this; - removeListener(event: string | symbol, listener: (...args: any[]) => void): this; - removeAllListeners(event?: string | symbol): this; - setMaxListeners(n: number): this; - getMaxListeners(): number; - listeners(event: string | symbol): Function[]; - emit(event: string | symbol, ...args: any[]): boolean; - listenerCount(type: string | symbol): number; - // Added in Node 6... - prependListener(event: string | symbol, listener: (...args: any[]) => void): this; - prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; - eventNames(): Array; - } + export interface Process extends EventEmitter { + stdout: WriteStream; + stderr: WriteStream; + stdin: ReadStream; + openStdin(): Socket; + argv: string[]; + argv0: string; + execArgv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + emitWarning(warning: string | Error, name?: string, ctor?: Function): void; + env: any; + exit(code?: number): void; + exitCode: number; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: ProcessVersions; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string | number): void; + pid: number; + title: string; + arch: string; + platform: Platform; + mainModule?: NodeModule; + memoryUsage(): MemoryUsage; + cpuUsage(previousValue?: CpuUsage): CpuUsage; + nextTick(callback: Function, ...args: any[]): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?: [number, number]): [number, number]; + domain: Domain; - export interface ReadableStream extends EventEmitter { - readable: boolean; - read(size?: number): string | Buffer; - setEncoding(encoding: string): this; - pause(): this; - resume(): this; - isPaused(): boolean; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): this; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: ReadableStream): this; - } + // Worker + send?(message: any, sendHandle?: any): void; + disconnect(): void; + connected: boolean; + } - export interface WritableStream extends EventEmitter { - writable: boolean; - write(buffer: Buffer | string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(cb?: Function): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + v8debug?: any; + } - export interface ReadWriteStream extends ReadableStream, WritableStream { } - - export interface Events extends EventEmitter { } - - export interface Domain extends Events { - run(fn: Function): void; - add(emitter: Events): void; - remove(emitter: Events): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - - addListener(event: string, listener: (...args: any[]) => void): this; - on(event: string, listener: (...args: any[]) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - removeListener(event: string, listener: (...args: any[]) => void): this; - removeAllListeners(event?: string): this; - } - - export interface MemoryUsage { - rss: number; - heapTotal: number; - heapUsed: number; - } - - export interface CpuUsage { - user: number; - system: number; - } - - export interface ProcessVersions { - http_parser: string; - node: string; - v8: string; - ares: string; - uv: string; - zlib: string; - modules: string; - openssl: string; - } - - type Platform = 'aix' - | 'android' - | 'darwin' - | 'freebsd' - | 'linux' - | 'openbsd' - | 'sunos' - | 'win32' - | 'cygwin'; - - type Signals = - "SIGABRT" | "SIGALRM" | "SIGBUS" | "SIGCHLD" | "SIGCONT" | "SIGFPE" | "SIGHUP" | "SIGILL" | "SIGINT" | "SIGIO" | - "SIGIOT" | "SIGKILL" | "SIGPIPE" | "SIGPOLL" | "SIGPROF" | "SIGPWR" | "SIGQUIT" | "SIGSEGV" | "SIGSTKFLT" | - "SIGSTOP" | "SIGSYS" | "SIGTERM" | "SIGTRAP" | "SIGTSTP" | "SIGTTIN" | "SIGTTOU" | "SIGUNUSED" | "SIGURG" | - "SIGUSR1" | "SIGUSR2" | "SIGVTALRM" | "SIGWINCH" | "SIGXCPU" | "SIGXFSZ" | "SIGBREAK" | "SIGLOST" | "SIGINFO"; - - type BeforeExitListener = (code: number) => void; - type DisconnectListener = () => void; - type ExitListener = (code: number) => void; - type RejectionHandledListener = (promise: Promise) => void; - type UncaughtExceptionListener = (error: Error) => void; - type UnhandledRejectionListener = (reason: any, promise: Promise) => void; - type WarningListener = (warning: Error) => void; - type MessageListener = (message: any, sendHandle: any) => void; - type SignalsListener = () => void; - type NewListenerListener = (type: string | symbol, listener: (...args: any[]) => void) => void; - type RemoveListenerListener = (type: string | symbol, listener: (...args: any[]) => void) => void; - - export interface Socket extends ReadWriteStream { - isTTY?: true; - } - - export interface ProcessEnv { - [key: string]: string | undefined; - } - - export interface WriteStream extends Socket { - columns?: number; - rows?: number; - _write(chunk: any, encoding: string, callback: Function): void; - _destroy(err: Error, callback: Function): void; - _final(callback: Function): void; - setDefaultEncoding(encoding: string): this; - cork(): void; - uncork(): void; - destroy(error?: Error): void; - } - export interface ReadStream extends Socket { - isRaw?: boolean; - setRawMode?(mode: boolean): void; - _read(size: number): void; - _destroy(err: Error, callback: Function): void; - push(chunk: any, encoding?: string): boolean; - destroy(error?: Error): void; - } - - export interface Process extends EventEmitter { - stdout: WriteStream; - stderr: WriteStream; - stdin: ReadStream; - openStdin(): Socket; - argv: string[]; - argv0: string; - execArgv: string[]; - execPath: string; - abort(): void; - chdir(directory: string): void; - cwd(): string; - emitWarning(warning: string | Error, name?: string, ctor?: Function): void; - env: ProcessEnv; - exit(code?: number): never; - exitCode: number; - getgid(): number; - setgid(id: number | string): void; - getuid(): number; - setuid(id: number | string): void; - geteuid(): number; - seteuid(id: number | string): void; - getegid(): number; - setegid(id: number | string): void; - getgroups(): number[]; - setgroups(groups: Array): void; - version: string; - versions: ProcessVersions; - config: { - target_defaults: { - cflags: any[]; - default_configuration: string; - defines: string[]; - include_dirs: string[]; - libraries: string[]; - }; - variables: { - clang: number; - host_arch: string; - node_install_npm: boolean; - node_install_waf: boolean; - node_prefix: string; - node_shared_openssl: boolean; - node_shared_v8: boolean; - node_shared_zlib: boolean; - node_use_dtrace: boolean; - node_use_etw: boolean; - node_use_openssl: boolean; - target_arch: string; - v8_no_strict_aliasing: number; - v8_use_snapshot: boolean; - visibility: string; - }; - }; - kill(pid: number, signal?: string | number): void; - pid: number; - title: string; - arch: string; - platform: Platform; - mainModule?: NodeModule; - memoryUsage(): MemoryUsage; - cpuUsage(previousValue?: CpuUsage): CpuUsage; - nextTick(callback: Function, ...args: any[]): void; - umask(mask?: number): number; - uptime(): number; - hrtime(time?: [number, number]): [number, number]; - domain: Domain; - - // Worker - send?(message: any, sendHandle?: any): void; - disconnect(): void; - connected: boolean; - - /** - * EventEmitter - * 1. beforeExit - * 2. disconnect - * 3. exit - * 4. message - * 5. rejectionHandled - * 6. uncaughtException - * 7. unhandledRejection - * 8. warning - * 9. message - * 10. - * 11. newListener/removeListener inherited from EventEmitter - */ - addListener(event: "beforeExit", listener: BeforeExitListener): this; - addListener(event: "disconnect", listener: DisconnectListener): this; - addListener(event: "exit", listener: ExitListener): this; - addListener(event: "rejectionHandled", listener: RejectionHandledListener): this; - addListener(event: "uncaughtException", listener: UncaughtExceptionListener): this; - addListener(event: "unhandledRejection", listener: UnhandledRejectionListener): this; - addListener(event: "warning", listener: WarningListener): this; - addListener(event: "message", listener: MessageListener): this; - addListener(event: Signals, listener: SignalsListener): this; - addListener(event: "newListener", listener: NewListenerListener): this; - addListener(event: "removeListener", listener: RemoveListenerListener): this; - - emit(event: "beforeExit", code: number): boolean; - emit(event: "disconnect"): boolean; - emit(event: "exit", code: number): boolean; - emit(event: "rejectionHandled", promise: Promise): boolean; - emit(event: "uncaughtException", error: Error): boolean; - emit(event: "unhandledRejection", reason: any, promise: Promise): boolean; - emit(event: "warning", warning: Error): boolean; - emit(event: "message", message: any, sendHandle: any): this; - emit(event: Signals): boolean; - emit(event: "newListener", eventName: string | symbol, listener: (...args: any[]) => void): this; - emit(event: "removeListener", eventName: string, listener: (...args: any[]) => void): this; - - on(event: "beforeExit", listener: BeforeExitListener): this; - on(event: "disconnect", listener: DisconnectListener): this; - on(event: "exit", listener: ExitListener): this; - on(event: "rejectionHandled", listener: RejectionHandledListener): this; - on(event: "uncaughtException", listener: UncaughtExceptionListener): this; - on(event: "unhandledRejection", listener: UnhandledRejectionListener): this; - on(event: "warning", listener: WarningListener): this; - on(event: "message", listener: MessageListener): this; - on(event: Signals, listener: SignalsListener): this; - on(event: "newListener", listener: NewListenerListener): this; - on(event: "removeListener", listener: RemoveListenerListener): this; - - once(event: "beforeExit", listener: BeforeExitListener): this; - once(event: "disconnect", listener: DisconnectListener): this; - once(event: "exit", listener: ExitListener): this; - once(event: "rejectionHandled", listener: RejectionHandledListener): this; - once(event: "uncaughtException", listener: UncaughtExceptionListener): this; - once(event: "unhandledRejection", listener: UnhandledRejectionListener): this; - once(event: "warning", listener: WarningListener): this; - once(event: "message", listener: MessageListener): this; - once(event: Signals, listener: SignalsListener): this; - once(event: "newListener", listener: NewListenerListener): this; - once(event: "removeListener", listener: RemoveListenerListener): this; - - prependListener(event: "beforeExit", listener: BeforeExitListener): this; - prependListener(event: "disconnect", listener: DisconnectListener): this; - prependListener(event: "exit", listener: ExitListener): this; - prependListener(event: "rejectionHandled", listener: RejectionHandledListener): this; - prependListener(event: "uncaughtException", listener: UncaughtExceptionListener): this; - prependListener(event: "unhandledRejection", listener: UnhandledRejectionListener): this; - prependListener(event: "warning", listener: WarningListener): this; - prependListener(event: "message", listener: MessageListener): this; - prependListener(event: Signals, listener: SignalsListener): this; - prependListener(event: "newListener", listener: NewListenerListener): this; - prependListener(event: "removeListener", listener: RemoveListenerListener): this; - - prependOnceListener(event: "beforeExit", listener: BeforeExitListener): this; - prependOnceListener(event: "disconnect", listener: DisconnectListener): this; - prependOnceListener(event: "exit", listener: ExitListener): this; - prependOnceListener(event: "rejectionHandled", listener: RejectionHandledListener): this; - prependOnceListener(event: "uncaughtException", listener: UncaughtExceptionListener): this; - prependOnceListener(event: "unhandledRejection", listener: UnhandledRejectionListener): this; - prependOnceListener(event: "warning", listener: WarningListener): this; - prependOnceListener(event: "message", listener: MessageListener): this; - prependOnceListener(event: Signals, listener: SignalsListener): this; - prependOnceListener(event: "newListener", listener: NewListenerListener): this; - prependOnceListener(event: "removeListener", listener: RemoveListenerListener): this; - - listeners(event: "beforeExit"): BeforeExitListener[]; - listeners(event: "disconnect"): DisconnectListener[]; - listeners(event: "exit"): ExitListener[]; - listeners(event: "rejectionHandled"): RejectionHandledListener[]; - listeners(event: "uncaughtException"): UncaughtExceptionListener[]; - listeners(event: "unhandledRejection"): UnhandledRejectionListener[]; - listeners(event: "warning"): WarningListener[]; - listeners(event: "message"): MessageListener[]; - listeners(event: Signals): SignalsListener[]; - listeners(event: "newListener"): NewListenerListener[]; - listeners(event: "removeListener"): RemoveListenerListener[]; - } - - export interface Global { - Array: typeof Array; - ArrayBuffer: typeof ArrayBuffer; - Boolean: typeof Boolean; - Buffer: typeof Buffer; - DataView: typeof DataView; - Date: typeof Date; - Error: typeof Error; - EvalError: typeof EvalError; - Float32Array: typeof Float32Array; - Float64Array: typeof Float64Array; - Function: typeof Function; - GLOBAL: Global; - Infinity: typeof Infinity; - Int16Array: typeof Int16Array; - Int32Array: typeof Int32Array; - Int8Array: typeof Int8Array; - Intl: typeof Intl; - JSON: typeof JSON; - Map: MapConstructor; - Math: typeof Math; - NaN: typeof NaN; - Number: typeof Number; - Object: typeof Object; - Promise: Function; - RangeError: typeof RangeError; - ReferenceError: typeof ReferenceError; - RegExp: typeof RegExp; - Set: SetConstructor; - String: typeof String; - Symbol: Function; - SyntaxError: typeof SyntaxError; - TypeError: typeof TypeError; - URIError: typeof URIError; - Uint16Array: typeof Uint16Array; - Uint32Array: typeof Uint32Array; - Uint8Array: typeof Uint8Array; - Uint8ClampedArray: Function; - WeakMap: WeakMapConstructor; - WeakSet: WeakSetConstructor; - clearImmediate: (immediateId: any) => void; - clearInterval: (intervalId: NodeJS.Timer) => void; - clearTimeout: (timeoutId: NodeJS.Timer) => void; - console: typeof console; - decodeURI: typeof decodeURI; - decodeURIComponent: typeof decodeURIComponent; - encodeURI: typeof encodeURI; - encodeURIComponent: typeof encodeURIComponent; - escape: (str: string) => string; - eval: typeof eval; - global: Global; - isFinite: typeof isFinite; - isNaN: typeof isNaN; - parseFloat: typeof parseFloat; - parseInt: typeof parseInt; - process: Process; - root: Global; - setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; - setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - undefined: typeof undefined; - unescape: (str: string) => string; - gc: () => void; - v8debug?: any; - } - - export interface Timer { - ref(): void; - unref(): void; - } - - class Module { - static runMain(): void; - static wrap(code: string): string; - - static Module: typeof Module; - - exports: any; - require: NodeRequireFunction; - id: string; - filename: string; - loaded: boolean; - parent: Module | null; - children: Module[]; - paths: string[]; - - constructor(id: string, parent?: Module); - } + export interface Timer { + ref(): void; + unref(): void; + } } interface IterableIterator { } @@ -814,59 +540,59 @@ interface IterableIterator { } * @deprecated */ interface NodeBuffer extends Uint8Array { - write(string: string, offset?: number, length?: number, encoding?: string): number; - toString(encoding?: string, start?: number, end?: number): string; - toJSON(): { type: 'Buffer', data: any[] }; - equals(otherBuffer: Buffer): boolean; - compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; - copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; - slice(start?: number, end?: number): Buffer; - writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readUInt8(offset: number, noAssert?: boolean): number; - readUInt16LE(offset: number, noAssert?: boolean): number; - readUInt16BE(offset: number, noAssert?: boolean): number; - readUInt32LE(offset: number, noAssert?: boolean): number; - readUInt32BE(offset: number, noAssert?: boolean): number; - readInt8(offset: number, noAssert?: boolean): number; - readInt16LE(offset: number, noAssert?: boolean): number; - readInt16BE(offset: number, noAssert?: boolean): number; - readInt32LE(offset: number, noAssert?: boolean): number; - readInt32BE(offset: number, noAssert?: boolean): number; - readFloatLE(offset: number, noAssert?: boolean): number; - readFloatBE(offset: number, noAssert?: boolean): number; - readDoubleLE(offset: number, noAssert?: boolean): number; - readDoubleBE(offset: number, noAssert?: boolean): number; - swap16(): Buffer; - swap32(): Buffer; - swap64(): Buffer; - writeUInt8(value: number, offset: number, noAssert?: boolean): number; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeInt8(value: number, offset: number, noAssert?: boolean): number; - writeInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeFloatLE(value: number, offset: number, noAssert?: boolean): number; - writeFloatBE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; - fill(value: any, offset?: number, end?: number): this; - indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; - lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; - entries(): IterableIterator<[number, number]>; - includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; - keys(): IterableIterator; - values(): IterableIterator; + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): { type: 'Buffer', data: any[] }; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + swap16(): Buffer; + swap32(): Buffer; + swap64(): Buffer; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): this; + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + entries(): IterableIterator<[number, number]>; + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; + keys(): IterableIterator; + values(): IterableIterator; } /************************************************ @@ -875,269 +601,205 @@ interface NodeBuffer extends Uint8Array { * * ************************************************/ declare module "buffer" { - export var INSPECT_MAX_BYTES: number; - var BuffType: typeof Buffer; - var SlowBuffType: typeof SlowBuffer; - export { BuffType as Buffer, SlowBuffType as SlowBuffer }; + export var INSPECT_MAX_BYTES: number; + var BuffType: typeof Buffer; + var SlowBuffType: typeof SlowBuffer; + export { BuffType as Buffer, SlowBuffType as SlowBuffer }; } declare module "querystring" { - export interface StringifyOptions { - encodeURIComponent?: Function; - } + export interface StringifyOptions { + encodeURIComponent?: Function; + } - export interface ParseOptions { - maxKeys?: number; - decodeURIComponent?: Function; - } + export interface ParseOptions { + maxKeys?: number; + decodeURIComponent?: Function; + } - interface ParsedUrlQuery { [key: string]: string | string[]; } - - export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): ParsedUrlQuery; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; - export function escape(str: string): string; - export function unescape(str: string): string; + export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; + export function escape(str: string): string; + export function unescape(str: string): string; } declare module "events" { - class internal extends NodeJS.EventEmitter { } + class internal extends NodeJS.EventEmitter { } - namespace internal { - export class EventEmitter extends internal { - static listenerCount(emitter: EventEmitter, event: string | symbol): number; // deprecated - static defaultMaxListeners: number; + namespace internal { + export class EventEmitter extends internal { + static listenerCount(emitter: EventEmitter, event: string | symbol): number; // deprecated + static defaultMaxListeners: number; - addListener(event: string | symbol, listener: (...args: any[]) => void): this; - on(event: string | symbol, listener: (...args: any[]) => void): this; - once(event: string | symbol, listener: (...args: any[]) => void): this; - prependListener(event: string | symbol, listener: (...args: any[]) => void): this; - prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; - removeListener(event: string | symbol, listener: (...args: any[]) => void): this; - removeAllListeners(event?: string | symbol): this; - setMaxListeners(n: number): this; - getMaxListeners(): number; - listeners(event: string | symbol): Function[]; - emit(event: string | symbol, ...args: any[]): boolean; - eventNames(): Array; - listenerCount(type: string | symbol): number; - } - } + addListener(event: string | symbol, listener: Function): this; + on(event: string | symbol, listener: Function): this; + once(event: string | symbol, listener: Function): this; + prependListener(event: string | symbol, listener: Function): this; + prependOnceListener(event: string | symbol, listener: Function): this; + removeListener(event: string | symbol, listener: Function): this; + removeAllListeners(event?: string | symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string | symbol): Function[]; + emit(event: string | symbol, ...args: any[]): boolean; + eventNames(): (string | symbol)[]; + listenerCount(type: string | symbol): number; + } + } - export = internal; + export = internal; } declare module "http" { - import * as events from "events"; - import * as net from "net"; - import * as stream from "stream"; - import { URL } from "url"; + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; - // incoming headers will never contain number - export interface IncomingHttpHeaders { - 'accept'?: string; - 'access-control-allow-origin'?: string; - 'access-control-allow-credentials'?: string; - 'access-control-expose-headers'?: string; - 'access-control-max-age'?: string; - 'access-control-allow-methods'?: string; - 'access-control-allow-headers'?: string; - 'accept-patch'?: string; - 'accept-ranges'?: string; - 'age'?: string; - 'allow'?: string; - 'alt-svc'?: string; - 'cache-control'?: string; - 'connection'?: string; - 'content-disposition'?: string; - 'content-encoding'?: string; - 'content-language'?: string; - 'content-length'?: string; - 'content-location'?: string; - 'content-range'?: string; - 'content-type'?: string; - 'date'?: string; - 'expires'?: string; - 'host'?: string; - 'last-modified'?: string; - 'location'?: string; - 'pragma'?: string; - 'proxy-authenticate'?: string; - 'public-key-pins'?: string; - 'retry-after'?: string; - 'set-cookie'?: string[]; - 'strict-transport-security'?: string; - 'trailer'?: string; - 'transfer-encoding'?: string; - 'tk'?: string; - 'upgrade'?: string; - 'vary'?: string; - 'via'?: string; - 'warning'?: string; - 'www-authenticate'?: string; - [header: string]: string | string[] | undefined; - } + export interface RequestOptions { + protocol?: string; + host?: string; + hostname?: string; + family?: number; + port?: number; + localAddress?: string; + socketPath?: string; + method?: string; + path?: string; + headers?: { [key: string]: any }; + auth?: string; + agent?: Agent | boolean; + timeout?: number; + } - // outgoing headers allows numbers (as they are converted internally to strings) - export interface OutgoingHttpHeaders { - [header: string]: number | string | string[] | undefined; - } - - export interface ClientRequestArgs { - protocol?: string; - host?: string; - hostname?: string; - family?: number; - port?: number | string; - defaultPort?: number | string; - localAddress?: string; - socketPath?: string; - method?: string; - path?: string; - headers?: OutgoingHttpHeaders; - auth?: string; - agent?: Agent | boolean; - _defaultAgent?: Agent; - timeout?: number; - // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L278 - createConnection?: (options: ClientRequestArgs, oncreate: (err: Error, socket: net.Socket) => void) => net.Socket; - } - - export class Server extends net.Server { - constructor(requestListener?: (req: IncomingMessage, res: ServerResponse) => void); - - setTimeout(msecs?: number, callback?: () => void): this; - setTimeout(callback: () => void): this; - maxHeadersCount: number; - timeout: number; - keepAliveTimeout: number; - } + export interface Server extends net.Server { + setTimeout(msecs: number, callback: Function): void; + maxHeadersCount: number; + timeout: number; + listening: boolean; + } /** * @deprecated Use IncomingMessage */ - export class ServerRequest extends IncomingMessage { - connection: net.Socket; - } + export interface ServerRequest extends IncomingMessage { + connection: net.Socket; + } + export interface ServerResponse extends stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; - // https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js - export class OutgoingMessage extends stream.Writable { - upgrading: boolean; - chunkedEncoding: boolean; - shouldKeepAlive: boolean; - useChunkedEncodingByDefault: boolean; - sendDate: boolean; - finished: boolean; - headersSent: boolean; - connection: net.Socket; + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + statusMessage: string; + headersSent: boolean; + setHeader(name: string, value: string | string[]): void; + setTimeout(msecs: number, callback: Function): ServerResponse; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + finished: boolean; - constructor(); + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; - setTimeout(msecs: number, callback?: () => void): this; - destroy(error: Error): void; - setHeader(name: string, value: number | string | string[]): void; - getHeader(name: string): number | string | string[] | undefined; - getHeaders(): OutgoingHttpHeaders; - getHeaderNames(): string[]; - hasHeader(name: string): boolean; - removeHeader(name: string): void; - addTrailers(headers: OutgoingHttpHeaders | Array<[string, string]>): void; - flushHeaders(): void; - } + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; - // https://github.com/nodejs/node/blob/master/lib/_http_server.js#L108-L256 - export class ServerResponse extends OutgoingMessage { - statusCode: number; - statusMessage: string; + setHeader(name: string, value: string | string[]): void; + getHeader(name: string): string; + removeHeader(name: string): void; + addTrailers(headers: any): void; - constructor(req: IncomingMessage); - - assignSocket(socket: net.Socket): void; - detachSocket(socket: net.Socket): void; - // https://github.com/nodejs/node/blob/master/test/parallel/test-http-write-callbacks.js#L53 - // no args in writeContinue callback - writeContinue(callback?: () => void): void; - writeHead(statusCode: number, reasonPhrase?: string, headers?: OutgoingHttpHeaders): void; - writeHead(statusCode: number, headers?: OutgoingHttpHeaders): void; - } - - // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L77 - export class ClientRequest extends OutgoingMessage { - connection: net.Socket; - socket: net.Socket; - aborted: number; - - constructor(url: string | URL | ClientRequestArgs, cb?: (res: IncomingMessage) => void); - - abort(): void; - onSocket(socket: net.Socket): void; - setTimeout(timeout: number, callback?: () => void): this; - setNoDelay(noDelay?: boolean): void; - setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; - } - - export class IncomingMessage extends stream.Readable { - constructor(socket: net.Socket); - - httpVersion: string; - httpVersionMajor: number; - httpVersionMinor: number; - connection: net.Socket; - headers: IncomingHttpHeaders; - rawHeaders: string[]; - trailers: { [key: string]: string | undefined }; - rawTrailers: string[]; - setTimeout(msecs: number, callback: () => void): this; + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface IncomingMessage extends stream.Readable { + httpVersion: string; + httpVersionMajor: number; + httpVersionMinor: number; + connection: net.Socket; + headers: any; + rawHeaders: string[]; + trailers: any; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; /** * Only valid for request obtained from http.Server. */ - method?: string; + method?: string; /** * Only valid for request obtained from http.Server. */ - url?: string; + url?: string; /** * Only valid for response obtained from http.ClientRequest. */ - statusCode?: number; + statusCode?: number; /** * Only valid for response obtained from http.ClientRequest. */ - statusMessage?: string; - socket: net.Socket; - destroy(error?: Error): void; - } - + statusMessage?: string; + socket: net.Socket; + destroy(error?: Error): void; + } /** * @deprecated Use IncomingMessage */ - export class ClientResponse extends IncomingMessage { } + export interface ClientResponse extends IncomingMessage { } - export interface AgentOptions { + export interface AgentOptions { /** * Keep sockets around in a pool to be used by other requests in the future. Default = false */ - keepAlive?: boolean; + keepAlive?: boolean; /** * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. * Only relevant if keepAlive is set to true. */ - keepAliveMsecs?: number; + keepAliveMsecs?: number; /** * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity */ - maxSockets?: number; + maxSockets?: number; /** * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. */ - maxFreeSockets?: number; - } + maxFreeSockets?: number; + } - export class Agent { - maxSockets: number; - sockets: any; - requests: any; + export class Agent { + maxSockets: number; + sockets: any; + requests: any; - constructor(opts?: AgentOptions); + constructor(opts?: AgentOptions); /** * Destroy any sockets that are currently in use by the agent. @@ -1145,61 +807,62 @@ declare module "http" { * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, * sockets may hang open for quite a long time before the server terminates them. */ - destroy(): void; - } + destroy(): void; + } - export var METHODS: string[]; + export var METHODS: string[]; - export var STATUS_CODES: { - [errorCode: number]: string | undefined; - [errorCode: string]: string | undefined; - }; - - export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; - export function createClient(port?: number, host?: string): any; - - // although RequestOptions are passed as ClientRequestArgs to ClientRequest directly, - // create interface RequestOptions would make the naming more clear to developers - export interface RequestOptions extends ClientRequestArgs { } - export function request(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest; - export function get(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest; - export var globalAgent: Agent; + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; } declare module "cluster" { - import * as child from "child_process"; - import * as events from "events"; - import * as net from "net"; + import * as child from "child_process"; + import * as events from "events"; + import * as net from "net"; - // interfaces - export interface ClusterSettings { - execArgv?: string[]; // default: process.execArgv - exec?: string; - args?: string[]; - silent?: boolean; - stdio?: any[]; - uid?: number; - gid?: number; - inspectPort?: number | (() => number); - } + // interfaces + export interface ClusterSettings { + execArgv?: string[]; // default: process.execArgv + exec?: string; + args?: string[]; + silent?: boolean; + stdio?: any[]; + uid?: number; + gid?: number; + } - export interface Address { - address: string; - port: number; - addressType: number | "udp4" | "udp6"; // 4, 6, -1, "udp4", "udp6" - } + export interface ClusterSetupMasterSettings { + exec?: string; // default: process.argv[1] + args?: string[]; // default: process.argv.slice(2) + silent?: boolean; // default: false + stdio?: any[]; + } - export class Worker extends events.EventEmitter { - id: number; - process: child.ChildProcess; - suicide: boolean; - send(message: any, sendHandle?: any, callback?: (error: Error) => void): boolean; - kill(signal?: string): void; - destroy(signal?: string): void; - disconnect(): void; - isConnected(): boolean; - isDead(): boolean; - exitedAfterDisconnect: boolean; + export interface Address { + address: string; + port: number; + addressType: number | "udp4" | "udp6"; // 4, 6, -1, "udp4", "udp6" + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any, callback?: (error: Error) => void): boolean; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + isConnected(): boolean; + isDead(): boolean; + exitedAfterDisconnect: boolean; /** * events.EventEmitter @@ -1210,68 +873,68 @@ declare module "cluster" { * 5. message * 6. online */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "disconnect", listener: () => void): this; - addListener(event: "error", listener: (error: Error) => void): this; - addListener(event: "exit", listener: (code: number, signal: string) => void): this; - addListener(event: "listening", listener: (address: Address) => void): this; - addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - addListener(event: "online", listener: () => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "disconnect", listener: () => void): this; + addListener(event: "error", listener: (error: Error) => void): this; + addListener(event: "exit", listener: (code: number, signal: string) => void): this; + addListener(event: "listening", listener: (address: Address) => void): this; + addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "disconnect"): boolean; - emit(event: "error", error: Error): boolean; - emit(event: "exit", code: number, signal: string): boolean; - emit(event: "listening", address: Address): boolean; - emit(event: "message", message: any, handle: net.Socket | net.Server): boolean; - emit(event: "online"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "disconnect", listener: () => void): boolean + emit(event: "error", listener: (error: Error) => void): boolean + emit(event: "exit", listener: (code: number, signal: string) => void): boolean + emit(event: "listening", listener: (address: Address) => void): boolean + emit(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): boolean + emit(event: "online", listener: () => void): boolean - on(event: string, listener: (...args: any[]) => void): this; - on(event: "disconnect", listener: () => void): this; - on(event: "error", listener: (error: Error) => void): this; - on(event: "exit", listener: (code: number, signal: string) => void): this; - on(event: "listening", listener: (address: Address) => void): this; - on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - on(event: "online", listener: () => void): this; + on(event: string, listener: Function): this; + on(event: "disconnect", listener: () => void): this; + on(event: "error", listener: (error: Error) => void): this; + on(event: "exit", listener: (code: number, signal: string) => void): this; + on(event: "listening", listener: (address: Address) => void): this; + on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: () => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "disconnect", listener: () => void): this; - once(event: "error", listener: (error: Error) => void): this; - once(event: "exit", listener: (code: number, signal: string) => void): this; - once(event: "listening", listener: (address: Address) => void): this; - once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - once(event: "online", listener: () => void): this; + once(event: string, listener: Function): this; + once(event: "disconnect", listener: () => void): this; + once(event: "error", listener: (error: Error) => void): this; + once(event: "exit", listener: (code: number, signal: string) => void): this; + once(event: "listening", listener: (address: Address) => void): this; + once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: () => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "disconnect", listener: () => void): this; - prependListener(event: "error", listener: (error: Error) => void): this; - prependListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependListener(event: "listening", listener: (address: Address) => void): this; - prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependListener(event: "online", listener: () => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "disconnect", listener: () => void): this; + prependListener(event: "error", listener: (error: Error) => void): this; + prependListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependListener(event: "listening", listener: (address: Address) => void): this; + prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: () => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "disconnect", listener: () => void): this; - prependOnceListener(event: "error", listener: (error: Error) => void): this; - prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependOnceListener(event: "listening", listener: (address: Address) => void): this; - prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependOnceListener(event: "online", listener: () => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "disconnect", listener: () => void): this; + prependOnceListener(event: "error", listener: (error: Error) => void): this; + prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "listening", listener: (address: Address) => void): this; + prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: () => void): this; + } - export interface Cluster extends events.EventEmitter { - Worker: Worker; - disconnect(callback?: Function): void; - fork(env?: any): Worker; - isMaster: boolean; - isWorker: boolean; - // TODO: cluster.schedulingPolicy - settings: ClusterSettings; - setupMaster(settings?: ClusterSettings): void; - worker?: Worker; - workers?: { - [index: string]: Worker | undefined - }; + export interface Cluster extends events.EventEmitter { + Worker: Worker; + disconnect(callback?: Function): void; + fork(env?: any): Worker; + isMaster: boolean; + isWorker: boolean; + // TODO: cluster.schedulingPolicy + settings: ClusterSettings; + setupMaster(settings?: ClusterSetupMasterSettings): void; + worker: Worker; + workers: { + [index: string]: Worker + }; /** * events.EventEmitter @@ -1283,72 +946,73 @@ declare module "cluster" { * 6. online * 7. setup */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "disconnect", listener: (worker: Worker) => void): this; - addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - addListener(event: "fork", listener: (worker: Worker) => void): this; - addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; - addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - addListener(event: "online", listener: (worker: Worker) => void): this; - addListener(event: "setup", listener: (settings: any) => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "disconnect", listener: (worker: Worker) => void): this; + addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + addListener(event: "fork", listener: (worker: Worker) => void): this; + addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: (worker: Worker) => void): this; + addListener(event: "setup", listener: (settings: any) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "disconnect", worker: Worker): boolean; - emit(event: "exit", worker: Worker, code: number, signal: string): boolean; - emit(event: "fork", worker: Worker): boolean; - emit(event: "listening", worker: Worker, address: Address): boolean; - emit(event: "message", worker: Worker, message: any, handle: net.Socket | net.Server): boolean; - emit(event: "online", worker: Worker): boolean; - emit(event: "setup", settings: any): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "disconnect", listener: (worker: Worker) => void): boolean; + emit(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): boolean; + emit(event: "fork", listener: (worker: Worker) => void): boolean; + emit(event: "listening", listener: (worker: Worker, address: Address) => void): boolean; + emit(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): boolean; + emit(event: "online", listener: (worker: Worker) => void): boolean; + emit(event: "setup", listener: (settings: any) => void): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "disconnect", listener: (worker: Worker) => void): this; - on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - on(event: "fork", listener: (worker: Worker) => void): this; - on(event: "listening", listener: (worker: Worker, address: Address) => void): this; - on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - on(event: "online", listener: (worker: Worker) => void): this; - on(event: "setup", listener: (settings: any) => void): this; + on(event: string, listener: Function): this; + on(event: "disconnect", listener: (worker: Worker) => void): this; + on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + on(event: "fork", listener: (worker: Worker) => void): this; + on(event: "listening", listener: (worker: Worker, address: Address) => void): this; + on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: (worker: Worker) => void): this; + on(event: "setup", listener: (settings: any) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "disconnect", listener: (worker: Worker) => void): this; - once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - once(event: "fork", listener: (worker: Worker) => void): this; - once(event: "listening", listener: (worker: Worker, address: Address) => void): this; - once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - once(event: "online", listener: (worker: Worker) => void): this; - once(event: "setup", listener: (settings: any) => void): this; + once(event: string, listener: Function): this; + once(event: "disconnect", listener: (worker: Worker) => void): this; + once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + once(event: "fork", listener: (worker: Worker) => void): this; + once(event: "listening", listener: (worker: Worker, address: Address) => void): this; + once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: (worker: Worker) => void): this; + once(event: "setup", listener: (settings: any) => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "disconnect", listener: (worker: Worker) => void): this; - prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - prependListener(event: "fork", listener: (worker: Worker) => void): this; - prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; - prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependListener(event: "online", listener: (worker: Worker) => void): this; - prependListener(event: "setup", listener: (settings: any) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependListener(event: "fork", listener: (worker: Worker) => void): this; + prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: (worker: Worker) => void): this; + prependListener(event: "setup", listener: (settings: any) => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this; - prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; - prependOnceListener(event: "fork", listener: (worker: Worker) => void): this; - prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; - prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. - prependOnceListener(event: "online", listener: (worker: Worker) => void): this; - prependOnceListener(event: "setup", listener: (settings: any) => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependOnceListener(event: "fork", listener: (worker: Worker) => void): this; + prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: (worker: Worker) => void): this; + prependOnceListener(event: "setup", listener: (settings: any) => void): this; - export function disconnect(callback?: Function): void; - export function fork(env?: any): Worker; - export var isMaster: boolean; - export var isWorker: boolean; - // TODO: cluster.schedulingPolicy - export var settings: ClusterSettings; - export function setupMaster(settings?: ClusterSettings): void; - export var worker: Worker; - export var workers: { - [index: string]: Worker | undefined - }; + } + + export function disconnect(callback?: Function): void; + export function fork(env?: any): Worker; + export var isMaster: boolean; + export var isWorker: boolean; + // TODO: cluster.schedulingPolicy + export var settings: ClusterSettings; + export function setupMaster(settings?: ClusterSetupMasterSettings): void; + export var worker: Worker; + export var workers: { + [index: string]: Worker + }; /** * events.EventEmitter @@ -1360,520 +1024,499 @@ declare module "cluster" { * 6. online * 7. setup */ - export function addListener(event: string, listener: (...args: any[]) => void): Cluster; - export function addListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function addListener(event: "fork", listener: (worker: Worker) => void): Cluster; - export function addListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function addListener(event: "online", listener: (worker: Worker) => void): Cluster; - export function addListener(event: "setup", listener: (settings: any) => void): Cluster; + export function addListener(event: string, listener: Function): Cluster; + export function addListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function addListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function addListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "setup", listener: (settings: any) => void): Cluster; - export function emit(event: string | symbol, ...args: any[]): boolean; - export function emit(event: "disconnect", worker: Worker): boolean; - export function emit(event: "exit", worker: Worker, code: number, signal: string): boolean; - export function emit(event: "fork", worker: Worker): boolean; - export function emit(event: "listening", worker: Worker, address: Address): boolean; - export function emit(event: "message", worker: Worker, message: any, handle: net.Socket | net.Server): boolean; - export function emit(event: "online", worker: Worker): boolean; - export function emit(event: "setup", settings: any): boolean; + export function emit(event: string | symbol, ...args: any[]): boolean; + export function emit(event: "disconnect", listener: (worker: Worker) => void): boolean; + export function emit(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): boolean; + export function emit(event: "fork", listener: (worker: Worker) => void): boolean; + export function emit(event: "listening", listener: (worker: Worker, address: Address) => void): boolean; + export function emit(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): boolean; + export function emit(event: "online", listener: (worker: Worker) => void): boolean; + export function emit(event: "setup", listener: (settings: any) => void): boolean; - export function on(event: string, listener: (...args: any[]) => void): Cluster; - export function on(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function on(event: "fork", listener: (worker: Worker) => void): Cluster; - export function on(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function on(event: "online", listener: (worker: Worker) => void): Cluster; - export function on(event: "setup", listener: (settings: any) => void): Cluster; + export function on(event: string, listener: Function): Cluster; + export function on(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function on(event: "fork", listener: (worker: Worker) => void): Cluster; + export function on(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function on(event: "online", listener: (worker: Worker) => void): Cluster; + export function on(event: "setup", listener: (settings: any) => void): Cluster; - export function once(event: string, listener: (...args: any[]) => void): Cluster; - export function once(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function once(event: "fork", listener: (worker: Worker) => void): Cluster; - export function once(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function once(event: "online", listener: (worker: Worker) => void): Cluster; - export function once(event: "setup", listener: (settings: any) => void): Cluster; + export function once(event: string, listener: Function): Cluster; + export function once(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function once(event: "fork", listener: (worker: Worker) => void): Cluster; + export function once(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function once(event: "online", listener: (worker: Worker) => void): Cluster; + export function once(event: "setup", listener: (settings: any) => void): Cluster; - export function removeListener(event: string, listener: (...args: any[]) => void): Cluster; - export function removeAllListeners(event?: string): Cluster; - export function setMaxListeners(n: number): Cluster; - export function getMaxListeners(): number; - export function listeners(event: string): Function[]; - export function listenerCount(type: string): number; + export function removeListener(event: string, listener: Function): Cluster; + export function removeAllListeners(event?: string): Cluster; + export function setMaxListeners(n: number): Cluster; + export function getMaxListeners(): number; + export function listeners(event: string): Function[]; + export function listenerCount(type: string): number; - export function prependListener(event: string, listener: (...args: any[]) => void): Cluster; - export function prependListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function prependListener(event: "fork", listener: (worker: Worker) => void): Cluster; - export function prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function prependListener(event: "online", listener: (worker: Worker) => void): Cluster; - export function prependListener(event: "setup", listener: (settings: any) => void): Cluster; + export function prependListener(event: string, listener: Function): Cluster; + export function prependListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "setup", listener: (settings: any) => void): Cluster; - export function prependOnceListener(event: string, listener: (...args: any[]) => void): Cluster; - export function prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; - export function prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; - export function prependOnceListener(event: "fork", listener: (worker: Worker) => void): Cluster; - export function prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; - export function prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. - export function prependOnceListener(event: "online", listener: (worker: Worker) => void): Cluster; - export function prependOnceListener(event: "setup", listener: (settings: any) => void): Cluster; + export function prependOnceListener(event: string, listener: Function): Cluster; + export function prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependOnceListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependOnceListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "setup", listener: (settings: any) => void): Cluster; - export function eventNames(): string[]; + export function eventNames(): string[]; } declare module "zlib" { - import * as stream from "stream"; + import * as stream from "stream"; - export interface ZlibOptions { - flush?: number; // default: zlib.constants.Z_NO_FLUSH - finishFlush?: number; // default: zlib.constants.Z_FINISH - chunkSize?: number; // default: 16*1024 - windowBits?: number; - level?: number; // compression only - memLevel?: number; // compression only - strategy?: number; // compression only - dictionary?: any; // deflate/inflate only, empty dictionary by default - } + export interface ZlibOptions { + flush?: number; // default: zlib.constants.Z_NO_FLUSH + finishFlush?: number; // default: zlib.constants.Z_FINISH + chunkSize?: number; // default: 16*1024 + windowBits?: number; + level?: number; // compression only + memLevel?: number; // compression only + strategy?: number; // compression only + dictionary?: any; // deflate/inflate only, empty dictionary by default + } - export interface Zlib { - readonly bytesRead: number; - close(callback?: () => void): void; - flush(kind?: number | (() => void), callback?: () => void): void; - } + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } - export interface ZlibParams { - params(level: number, strategy: number, callback: () => void): void; - } + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; - export interface ZlibReset { - reset(): void; - } + export function deflate(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; + export function deflate(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; + export function deflateSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + export function deflateRaw(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; + export function deflateRaw(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; + export function deflateRawSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + export function gzip(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; + export function gzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; + export function gzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + export function gunzip(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; + export function gunzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; + export function gunzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + export function inflate(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; + export function inflate(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; + export function inflateSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + export function inflateRaw(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; + export function inflateRaw(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; + export function inflateRawSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + export function unzip(buf: Buffer | string, callback: (error: Error, result: Buffer) => void): void; + export function unzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error, result: Buffer) => void): void; + export function unzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export interface Gzip extends stream.Transform, Zlib { } - export interface Gunzip extends stream.Transform, Zlib { } - export interface Deflate extends stream.Transform, Zlib, ZlibReset, ZlibParams { } - export interface Inflate extends stream.Transform, Zlib, ZlibReset { } - export interface DeflateRaw extends stream.Transform, Zlib, ZlibReset, ZlibParams { } - export interface InflateRaw extends stream.Transform, Zlib, ZlibReset { } - export interface Unzip extends stream.Transform, Zlib { } + export namespace constants { + // Allowed flush values. - export function createGzip(options?: ZlibOptions): Gzip; - export function createGunzip(options?: ZlibOptions): Gunzip; - export function createDeflate(options?: ZlibOptions): Deflate; - export function createInflate(options?: ZlibOptions): Inflate; - export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; - export function createInflateRaw(options?: ZlibOptions): InflateRaw; - export function createUnzip(options?: ZlibOptions): Unzip; + export const Z_NO_FLUSH: number; + export const Z_PARTIAL_FLUSH: number; + export const Z_SYNC_FLUSH: number; + export const Z_FULL_FLUSH: number; + export const Z_FINISH: number; + export const Z_BLOCK: number; + export const Z_TREES: number; - export function deflate(buf: Buffer | string, callback: (error: Error | null, result: Buffer) => void): void; - export function deflate(buf: Buffer | string, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; - export function deflateSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function deflateRaw(buf: Buffer | string, callback: (error: Error | null, result: Buffer) => void): void; - export function deflateRaw(buf: Buffer | string, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; - export function deflateRawSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function gzip(buf: Buffer | string, callback: (error: Error | null, result: Buffer) => void): void; - export function gzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; - export function gzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function gunzip(buf: Buffer | string, callback: (error: Error | null, result: Buffer) => void): void; - export function gunzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; - export function gunzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function inflate(buf: Buffer | string, callback: (error: Error | null, result: Buffer) => void): void; - export function inflate(buf: Buffer | string, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; - export function inflateSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function inflateRaw(buf: Buffer | string, callback: (error: Error | null, result: Buffer) => void): void; - export function inflateRaw(buf: Buffer | string, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; - export function inflateRawSync(buf: Buffer | string, options?: ZlibOptions): Buffer; - export function unzip(buf: Buffer | string, callback: (error: Error | null, result: Buffer) => void): void; - export function unzip(buf: Buffer | string, options: ZlibOptions, callback: (error: Error | null, result: Buffer) => void): void; - export function unzipSync(buf: Buffer | string, options?: ZlibOptions): Buffer; + // Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events. - export namespace constants { - // Allowed flush values. + export const Z_OK: number; + export const Z_STREAM_END: number; + export const Z_NEED_DICT: number; + export const Z_ERRNO: number; + export const Z_STREAM_ERROR: number; + export const Z_DATA_ERROR: number; + export const Z_MEM_ERROR: number; + export const Z_BUF_ERROR: number; + export const Z_VERSION_ERROR: number; - export const Z_NO_FLUSH: number; - export const Z_PARTIAL_FLUSH: number; - export const Z_SYNC_FLUSH: number; - export const Z_FULL_FLUSH: number; - export const Z_FINISH: number; - export const Z_BLOCK: number; - export const Z_TREES: number; + // Compression levels. - // Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events. + export const Z_NO_COMPRESSION: number; + export const Z_BEST_SPEED: number; + export const Z_BEST_COMPRESSION: number; + export const Z_DEFAULT_COMPRESSION: number; - export const Z_OK: number; - export const Z_STREAM_END: number; - export const Z_NEED_DICT: number; - export const Z_ERRNO: number; - export const Z_STREAM_ERROR: number; - export const Z_DATA_ERROR: number; - export const Z_MEM_ERROR: number; - export const Z_BUF_ERROR: number; - export const Z_VERSION_ERROR: number; + // Compression strategy. - // Compression levels. + export const Z_FILTERED: number; + export const Z_HUFFMAN_ONLY: number; + export const Z_RLE: number; + export const Z_FIXED: number; + export const Z_DEFAULT_STRATEGY: number; + } - export const Z_NO_COMPRESSION: number; - export const Z_BEST_SPEED: number; - export const Z_BEST_COMPRESSION: number; - export const Z_DEFAULT_COMPRESSION: number; - - // Compression strategy. - - export const Z_FILTERED: number; - export const Z_HUFFMAN_ONLY: number; - export const Z_RLE: number; - export const Z_FIXED: number; - export const Z_DEFAULT_STRATEGY: number; - } - - // Constants - export var Z_NO_FLUSH: number; - export var Z_PARTIAL_FLUSH: number; - export var Z_SYNC_FLUSH: number; - export var Z_FULL_FLUSH: number; - export var Z_FINISH: number; - export var Z_BLOCK: number; - export var Z_TREES: number; - export var Z_OK: number; - export var Z_STREAM_END: number; - export var Z_NEED_DICT: number; - export var Z_ERRNO: number; - export var Z_STREAM_ERROR: number; - export var Z_DATA_ERROR: number; - export var Z_MEM_ERROR: number; - export var Z_BUF_ERROR: number; - export var Z_VERSION_ERROR: number; - export var Z_NO_COMPRESSION: number; - export var Z_BEST_SPEED: number; - export var Z_BEST_COMPRESSION: number; - export var Z_DEFAULT_COMPRESSION: number; - export var Z_FILTERED: number; - export var Z_HUFFMAN_ONLY: number; - export var Z_RLE: number; - export var Z_FIXED: number; - export var Z_DEFAULT_STRATEGY: number; - export var Z_BINARY: number; - export var Z_TEXT: number; - export var Z_ASCII: number; - export var Z_UNKNOWN: number; - export var Z_DEFLATED: number; + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; } declare module "os" { - export interface CpuInfo { - model: string; - speed: number; - times: { - user: number; - nice: number; - sys: number; - idle: number; - irq: number; - }; - } + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + }; + } - export interface NetworkInterfaceBase { - address: string; - netmask: string; - mac: string; - internal: boolean; - } + export interface NetworkInterfaceInfo { + address: string; + netmask: string; + family: string; + mac: string; + internal: boolean; + } - export interface NetworkInterfaceInfoIPv4 extends NetworkInterfaceBase { - family: "IPv4"; - } - - export interface NetworkInterfaceInfoIPv6 extends NetworkInterfaceBase { - family: "IPv6"; - scopeid: number; - } - - export type NetworkInterfaceInfo = NetworkInterfaceInfoIPv4 | NetworkInterfaceInfoIPv6; - - export function hostname(): string; - export function loadavg(): number[]; - export function uptime(): number; - export function freemem(): number; - export function totalmem(): number; - export function cpus(): CpuInfo[]; - export function type(): string; - export function release(): string; - export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; - export function homedir(): string; - export function userInfo(options?: { encoding: string }): { username: string, uid: number, gid: number, shell: any, homedir: string }; - export var constants: { - UV_UDP_REUSEADDR: number, - signals: { - SIGHUP: number; - SIGINT: number; - SIGQUIT: number; - SIGILL: number; - SIGTRAP: number; - SIGABRT: number; - SIGIOT: number; - SIGBUS: number; - SIGFPE: number; - SIGKILL: number; - SIGUSR1: number; - SIGSEGV: number; - SIGUSR2: number; - SIGPIPE: number; - SIGALRM: number; - SIGTERM: number; - SIGCHLD: number; - SIGSTKFLT: number; - SIGCONT: number; - SIGSTOP: number; - SIGTSTP: number; - SIGTTIN: number; - SIGTTOU: number; - SIGURG: number; - SIGXCPU: number; - SIGXFSZ: number; - SIGVTALRM: number; - SIGPROF: number; - SIGWINCH: number; - SIGIO: number; - SIGPOLL: number; - SIGPWR: number; - SIGSYS: number; - SIGUNUSED: number; - }, - errno: { - E2BIG: number; - EACCES: number; - EADDRINUSE: number; - EADDRNOTAVAIL: number; - EAFNOSUPPORT: number; - EAGAIN: number; - EALREADY: number; - EBADF: number; - EBADMSG: number; - EBUSY: number; - ECANCELED: number; - ECHILD: number; - ECONNABORTED: number; - ECONNREFUSED: number; - ECONNRESET: number; - EDEADLK: number; - EDESTADDRREQ: number; - EDOM: number; - EDQUOT: number; - EEXIST: number; - EFAULT: number; - EFBIG: number; - EHOSTUNREACH: number; - EIDRM: number; - EILSEQ: number; - EINPROGRESS: number; - EINTR: number; - EINVAL: number; - EIO: number; - EISCONN: number; - EISDIR: number; - ELOOP: number; - EMFILE: number; - EMLINK: number; - EMSGSIZE: number; - EMULTIHOP: number; - ENAMETOOLONG: number; - ENETDOWN: number; - ENETRESET: number; - ENETUNREACH: number; - ENFILE: number; - ENOBUFS: number; - ENODATA: number; - ENODEV: number; - ENOENT: number; - ENOEXEC: number; - ENOLCK: number; - ENOLINK: number; - ENOMEM: number; - ENOMSG: number; - ENOPROTOOPT: number; - ENOSPC: number; - ENOSR: number; - ENOSTR: number; - ENOSYS: number; - ENOTCONN: number; - ENOTDIR: number; - ENOTEMPTY: number; - ENOTSOCK: number; - ENOTSUP: number; - ENOTTY: number; - ENXIO: number; - EOPNOTSUPP: number; - EOVERFLOW: number; - EPERM: number; - EPIPE: number; - EPROTO: number; - EPROTONOSUPPORT: number; - EPROTOTYPE: number; - ERANGE: number; - EROFS: number; - ESPIPE: number; - ESRCH: number; - ESTALE: number; - ETIME: number; - ETIMEDOUT: number; - ETXTBSY: number; - EWOULDBLOCK: number; - EXDEV: number; - }, - }; - export function arch(): string; - export function platform(): NodeJS.Platform; - export function tmpdir(): string; - export const EOL: string; - export function endianness(): "BE" | "LE"; + export function hostname(): string; + export function loadavg(): number[]; + export function uptime(): number; + export function freemem(): number; + export function totalmem(): number; + export function cpus(): CpuInfo[]; + export function type(): string; + export function release(): string; + export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; + export function homedir(): string; + export function userInfo(options?: { encoding: string }): { username: string, uid: number, gid: number, shell: any, homedir: string } + export var constants: { + UV_UDP_REUSEADDR: number, + signals: { + SIGHUP: number; + SIGINT: number; + SIGQUIT: number; + SIGILL: number; + SIGTRAP: number; + SIGABRT: number; + SIGIOT: number; + SIGBUS: number; + SIGFPE: number; + SIGKILL: number; + SIGUSR1: number; + SIGSEGV: number; + SIGUSR2: number; + SIGPIPE: number; + SIGALRM: number; + SIGTERM: number; + SIGCHLD: number; + SIGSTKFLT: number; + SIGCONT: number; + SIGSTOP: number; + SIGTSTP: number; + SIGTTIN: number; + SIGTTOU: number; + SIGURG: number; + SIGXCPU: number; + SIGXFSZ: number; + SIGVTALRM: number; + SIGPROF: number; + SIGWINCH: number; + SIGIO: number; + SIGPOLL: number; + SIGPWR: number; + SIGSYS: number; + SIGUNUSED: number; + }, + errno: { + E2BIG: number; + EACCES: number; + EADDRINUSE: number; + EADDRNOTAVAIL: number; + EAFNOSUPPORT: number; + EAGAIN: number; + EALREADY: number; + EBADF: number; + EBADMSG: number; + EBUSY: number; + ECANCELED: number; + ECHILD: number; + ECONNABORTED: number; + ECONNREFUSED: number; + ECONNRESET: number; + EDEADLK: number; + EDESTADDRREQ: number; + EDOM: number; + EDQUOT: number; + EEXIST: number; + EFAULT: number; + EFBIG: number; + EHOSTUNREACH: number; + EIDRM: number; + EILSEQ: number; + EINPROGRESS: number; + EINTR: number; + EINVAL: number; + EIO: number; + EISCONN: number; + EISDIR: number; + ELOOP: number; + EMFILE: number; + EMLINK: number; + EMSGSIZE: number; + EMULTIHOP: number; + ENAMETOOLONG: number; + ENETDOWN: number; + ENETRESET: number; + ENETUNREACH: number; + ENFILE: number; + ENOBUFS: number; + ENODATA: number; + ENODEV: number; + ENOENT: number; + ENOEXEC: number; + ENOLCK: number; + ENOLINK: number; + ENOMEM: number; + ENOMSG: number; + ENOPROTOOPT: number; + ENOSPC: number; + ENOSR: number; + ENOSTR: number; + ENOSYS: number; + ENOTCONN: number; + ENOTDIR: number; + ENOTEMPTY: number; + ENOTSOCK: number; + ENOTSUP: number; + ENOTTY: number; + ENXIO: number; + EOPNOTSUPP: number; + EOVERFLOW: number; + EPERM: number; + EPIPE: number; + EPROTO: number; + EPROTONOSUPPORT: number; + EPROTOTYPE: number; + ERANGE: number; + EROFS: number; + ESPIPE: number; + ESRCH: number; + ESTALE: number; + ETIME: number; + ETIMEDOUT: number; + ETXTBSY: number; + EWOULDBLOCK: number; + EXDEV: number; + }, + }; + export function arch(): string; + export function platform(): NodeJS.Platform; + export function tmpdir(): string; + export var EOL: string; + export function endianness(): "BE" | "LE"; } declare module "https" { - import * as tls from "tls"; - import * as events from "events"; - import * as http from "http"; - import { URL } from "url"; + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; - export type ServerOptions = tls.SecureContextOptions & tls.TlsOptions; + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string, cb: (err: Error, ctx: tls.SecureContext) => any) => any; + } - // see https://nodejs.org/docs/latest-v8.x/api/https.html#https_https_request_options_callback - type extendedRequestKeys = "pfx" | - "key" | - "passphrase" | - "cert" | - "ca" | - "ciphers" | - "rejectUnauthorized" | - "secureProtocol" | - "servername"; + export interface RequestOptions extends http.RequestOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + } - export type RequestOptions = http.RequestOptions & Pick; + export interface Agent extends http.Agent { } - export interface AgentOptions extends http.AgentOptions, tls.ConnectionOptions { - rejectUnauthorized?: boolean; - maxCachedSessions?: number; - } + export interface AgentOptions extends http.AgentOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + maxCachedSessions?: number; + } - export class Agent extends http.Agent { - constructor(options?: AgentOptions); - } - - export class Server extends tls.Server { - setTimeout(callback: () => void): this; - setTimeout(msecs?: number, callback?: () => void): this; - timeout: number; - keepAliveTimeout: number; - } - - export function createServer(options: ServerOptions, requestListener?: (req: http.IncomingMessage, res: http.ServerResponse) => void): Server; - export function request(options: RequestOptions | string | URL, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; - export function get(options: RequestOptions | string | URL, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; - export var globalAgent: Agent; + export var Agent: { + new(options?: AgentOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export var globalAgent: Agent; } declare module "punycode" { - export function decode(string: string): string; - export function encode(string: string): string; - export function toUnicode(domain: string): string; - export function toASCII(domain: string): string; - export var ucs2: ucs2; - interface ucs2 { - decode(string: string): number[]; - encode(codePoints: number[]): string; - } - export var version: any; + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): number[]; + encode(codePoints: number[]): string; + } + export var version: any; } declare module "repl" { - import * as stream from "stream"; - import * as readline from "readline"; + import * as stream from "stream"; + import * as readline from "readline"; - export interface ReplOptions { - prompt?: string; - input?: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - terminal?: boolean; - eval?: Function; - useColors?: boolean; - useGlobal?: boolean; - ignoreUndefined?: boolean; - writer?: Function; - completer?: Function; - replMode?: any; - breakEvalOnSigint?: any; - } + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + completer?: Function; + replMode?: any; + breakEvalOnSigint?: any; + } - export interface REPLServer extends readline.ReadLine { - context: any; - inputStream: NodeJS.ReadableStream; - outputStream: NodeJS.WritableStream; - - defineCommand(keyword: string, cmd: Function | { help: string, action: Function }): void; - displayPrompt(preserveCursor?: boolean): void; + export interface REPLServer extends readline.ReadLine { + context: any; + defineCommand(keyword: string, cmd: Function | { help: string, action: Function }): void; + displayPrompt(preserveCursor?: boolean): void; /** * events.EventEmitter * 1. exit * 2. reset - */ + **/ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "exit", listener: () => void): this; - addListener(event: "reset", listener: (...args: any[]) => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "exit", listener: () => void): this; + addListener(event: "reset", listener: Function): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "exit"): boolean; - emit(event: "reset", context: any): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "exit"): boolean; + emit(event: "reset", context: any): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "exit", listener: () => void): this; - on(event: "reset", listener: (...args: any[]) => void): this; + on(event: string, listener: Function): this; + on(event: "exit", listener: () => void): this; + on(event: "reset", listener: Function): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "exit", listener: () => void): this; - once(event: "reset", listener: (...args: any[]) => void): this; + once(event: string, listener: Function): this; + once(event: "exit", listener: () => void): this; + once(event: "reset", listener: Function): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "exit", listener: () => void): this; - prependListener(event: "reset", listener: (...args: any[]) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "exit", listener: () => void): this; + prependListener(event: "reset", listener: Function): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "exit", listener: () => void): this; - prependOnceListener(event: "reset", listener: (...args: any[]) => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "exit", listener: () => void): this; + prependOnceListener(event: "reset", listener: Function): this; + } - export function start(options?: string | ReplOptions): REPLServer; - - export class Recoverable extends SyntaxError { - err: Error; - - constructor(err: Error); - } + export function start(options?: string | ReplOptions): REPLServer; } declare module "readline" { - import * as events from "events"; - import * as stream from "stream"; + import * as events from "events"; + import * as stream from "stream"; - export interface Key { - sequence?: string; - name?: string; - ctrl?: boolean; - meta?: boolean; - shift?: boolean; - } + export interface Key { + sequence?: string; + name?: string; + ctrl?: boolean; + meta?: boolean; + shift?: boolean; + } - export interface ReadLine extends events.EventEmitter { - setPrompt(prompt: string): void; - prompt(preserveCursor?: boolean): void; - question(query: string, callback: (answer: string) => void): void; - pause(): ReadLine; - resume(): ReadLine; - close(): void; - write(data: string | Buffer, key?: Key): void; + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: (answer: string) => void): void; + pause(): ReadLine; + resume(): ReadLine; + close(): void; + write(data: string | Buffer, key?: Key): void; /** * events.EventEmitter @@ -1884,138 +1527,138 @@ declare module "readline" { * 5. SIGCONT * 6. SIGINT * 7. SIGTSTP - */ + **/ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "line", listener: (input: any) => void): this; - addListener(event: "pause", listener: () => void): this; - addListener(event: "resume", listener: () => void): this; - addListener(event: "SIGCONT", listener: () => void): this; - addListener(event: "SIGINT", listener: () => void): this; - addListener(event: "SIGTSTP", listener: () => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "line", listener: (input: any) => void): this; + addListener(event: "pause", listener: () => void): this; + addListener(event: "resume", listener: () => void): this; + addListener(event: "SIGCONT", listener: () => void): this; + addListener(event: "SIGINT", listener: () => void): this; + addListener(event: "SIGTSTP", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "line", input: any): boolean; - emit(event: "pause"): boolean; - emit(event: "resume"): boolean; - emit(event: "SIGCONT"): boolean; - emit(event: "SIGINT"): boolean; - emit(event: "SIGTSTP"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "line", input: any): boolean; + emit(event: "pause"): boolean; + emit(event: "resume"): boolean; + emit(event: "SIGCONT"): boolean; + emit(event: "SIGINT"): boolean; + emit(event: "SIGTSTP"): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: () => void): this; - on(event: "line", listener: (input: any) => void): this; - on(event: "pause", listener: () => void): this; - on(event: "resume", listener: () => void): this; - on(event: "SIGCONT", listener: () => void): this; - on(event: "SIGINT", listener: () => void): this; - on(event: "SIGTSTP", listener: () => void): this; + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "line", listener: (input: any) => void): this; + on(event: "pause", listener: () => void): this; + on(event: "resume", listener: () => void): this; + on(event: "SIGCONT", listener: () => void): this; + on(event: "SIGINT", listener: () => void): this; + on(event: "SIGTSTP", listener: () => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: () => void): this; - once(event: "line", listener: (input: any) => void): this; - once(event: "pause", listener: () => void): this; - once(event: "resume", listener: () => void): this; - once(event: "SIGCONT", listener: () => void): this; - once(event: "SIGINT", listener: () => void): this; - once(event: "SIGTSTP", listener: () => void): this; + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "line", listener: (input: any) => void): this; + once(event: "pause", listener: () => void): this; + once(event: "resume", listener: () => void): this; + once(event: "SIGCONT", listener: () => void): this; + once(event: "SIGINT", listener: () => void): this; + once(event: "SIGTSTP", listener: () => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "line", listener: (input: any) => void): this; - prependListener(event: "pause", listener: () => void): this; - prependListener(event: "resume", listener: () => void): this; - prependListener(event: "SIGCONT", listener: () => void): this; - prependListener(event: "SIGINT", listener: () => void): this; - prependListener(event: "SIGTSTP", listener: () => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "line", listener: (input: any) => void): this; + prependListener(event: "pause", listener: () => void): this; + prependListener(event: "resume", listener: () => void): this; + prependListener(event: "SIGCONT", listener: () => void): this; + prependListener(event: "SIGINT", listener: () => void): this; + prependListener(event: "SIGTSTP", listener: () => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "line", listener: (input: any) => void): this; - prependOnceListener(event: "pause", listener: () => void): this; - prependOnceListener(event: "resume", listener: () => void): this; - prependOnceListener(event: "SIGCONT", listener: () => void): this; - prependOnceListener(event: "SIGINT", listener: () => void): this; - prependOnceListener(event: "SIGTSTP", listener: () => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "line", listener: (input: any) => void): this; + prependOnceListener(event: "pause", listener: () => void): this; + prependOnceListener(event: "resume", listener: () => void): this; + prependOnceListener(event: "SIGCONT", listener: () => void): this; + prependOnceListener(event: "SIGINT", listener: () => void): this; + prependOnceListener(event: "SIGTSTP", listener: () => void): this; + } - type Completer = (line: string) => CompleterResult; - type AsyncCompleter = (line: string, callback: (err: any, result: CompleterResult) => void) => any; + type Completer = (line: string) => CompleterResult; + type AsyncCompleter = (line: string, callback: (err: any, result: CompleterResult) => void) => any; - export type CompleterResult = [string[], string]; + export type CompleterResult = [string[], string]; - export interface ReadLineOptions { - input: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - completer?: Completer | AsyncCompleter; - terminal?: boolean; - historySize?: number; - } + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + completer?: Completer | AsyncCompleter; + terminal?: boolean; + historySize?: number; + prompt?: string; + crlfDelay?: number; + removeHistoryDuplicates?: boolean; + } - export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer | AsyncCompleter, terminal?: boolean): ReadLine; - export function createInterface(options: ReadLineOptions): ReadLine; + export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer | AsyncCompleter, terminal?: boolean): ReadLine; + export function createInterface(options: ReadLineOptions): ReadLine; - export function cursorTo(stream: NodeJS.WritableStream, x: number, y?: number): void; - export function emitKeypressEvents(stream: NodeJS.ReadableStream, interface?: ReadLine): void; - export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; - export function clearLine(stream: NodeJS.WritableStream, dir: number): void; - export function clearScreenDown(stream: NodeJS.WritableStream): void; + export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; + export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; + export function clearLine(stream: NodeJS.WritableStream, dir: number): void; + export function clearScreenDown(stream: NodeJS.WritableStream): void; } declare module "vm" { - export interface Context { } - export interface ScriptOptions { - filename?: string; - lineOffset?: number; - columnOffset?: number; - displayErrors?: boolean; - timeout?: number; - cachedData?: Buffer; - produceCachedData?: boolean; - } - export interface RunningScriptOptions { - filename?: string; - lineOffset?: number; - columnOffset?: number; - displayErrors?: boolean; - timeout?: number; - } - export class Script { - constructor(code: string, options?: ScriptOptions); - runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; - runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; - runInThisContext(options?: RunningScriptOptions): any; - } - export function createContext(sandbox?: Context): Context; - export function isContext(sandbox: Context): boolean; - export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; - export function runInDebugContext(code: string): any; - export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; - export function runInThisContext(code: string, options?: RunningScriptOptions): any; + export interface Context { } + export interface ScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + cachedData?: Buffer; + produceCachedData?: boolean; + } + export interface RunningScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + } + export class Script { + constructor(code: string, options?: ScriptOptions); + runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; + runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; + runInThisContext(options?: RunningScriptOptions): any; + } + export function createContext(sandbox?: Context): Context; + export function isContext(sandbox: Context): boolean; + export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; + export function runInDebugContext(code: string): any; + export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; + export function runInThisContext(code: string, options?: RunningScriptOptions): any; } declare module "child_process" { - import * as events from "events"; - import * as stream from "stream"; - import * as net from "net"; + import * as events from "events"; + import * as stream from "stream"; + import * as net from "net"; - export interface ChildProcess extends events.EventEmitter { - stdin: stream.Writable; - stdout: stream.Readable; - stderr: stream.Readable; - stdio: [stream.Writable, stream.Readable, stream.Readable]; - killed: boolean; - pid: number; - kill(signal?: string): void; - send(message: any, callback?: (error: Error) => void): boolean; - send(message: any, sendHandle?: net.Socket | net.Server, callback?: (error: Error) => void): boolean; - send(message: any, sendHandle?: net.Socket | net.Server, options?: MessageOptions, callback?: (error: Error) => void): boolean; - connected: boolean; - disconnect(): void; - unref(): void; - ref(): void; + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + stdio: [stream.Writable, stream.Readable, stream.Readable]; + killed: boolean; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle?: any): boolean; + connected: boolean; + disconnect(): void; + unref(): void; + ref(): void; /** * events.EventEmitter @@ -2024,610 +1667,464 @@ declare module "child_process" { * 3. error * 4. exit * 5. message - */ + **/ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: (code: number, signal: string) => void): this; - addListener(event: "disconnect", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "exit", listener: (code: number, signal: string) => void): this; - addListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: (code: number, signal: string) => void): this; + addListener(event: "disconnect", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "exit", listener: (code: number, signal: string) => void): this; + addListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close", code: number, signal: string): boolean; - emit(event: "disconnect"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "exit", code: number, signal: string): boolean; - emit(event: "message", message: any, sendHandle: net.Socket | net.Server): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close", code: number, signal: string): boolean; + emit(event: "disconnect"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "exit", code: number, signal: string): boolean; + emit(event: "message", message: any, sendHandle: net.Socket | net.Server): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: (code: number, signal: string) => void): this; - on(event: "disconnect", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "exit", listener: (code: number, signal: string) => void): this; - on(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + on(event: string, listener: Function): this; + on(event: "close", listener: (code: number, signal: string) => void): this; + on(event: "disconnect", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "exit", listener: (code: number, signal: string) => void): this; + on(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: (code: number, signal: string) => void): this; - once(event: "disconnect", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "exit", listener: (code: number, signal: string) => void): this; - once(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + once(event: string, listener: Function): this; + once(event: "close", listener: (code: number, signal: string) => void): this; + once(event: "disconnect", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "exit", listener: (code: number, signal: string) => void): this; + once(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: (code: number, signal: string) => void): this; - prependListener(event: "disconnect", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: (code: number, signal: string) => void): this; + prependListener(event: "disconnect", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: (code: number, signal: string) => void): this; - prependOnceListener(event: "disconnect", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; - prependOnceListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "disconnect", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "message", listener: (message: any, sendHandle: net.Socket | net.Server) => void): this; + } - export interface MessageOptions { - keepOpen?: boolean; - } + export interface SpawnOptions { + cwd?: string; + env?: any; + stdio?: any; + detached?: boolean; + uid?: number; + gid?: number; + shell?: boolean | string; + windowsVerbatimArguments?: boolean; + } + export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; - export interface SpawnOptions { - cwd?: string; - env?: any; - stdio?: any; - detached?: boolean; - uid?: number; - gid?: number; - shell?: boolean | string; - windowsVerbatimArguments?: boolean; - } + export interface ExecOptions { + cwd?: string; + env?: any; + shell?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecOptionsWithStringEncoding extends ExecOptions { + encoding: BufferEncoding; + } + export interface ExecOptionsWithBufferEncoding extends ExecOptions { + encoding: string; // specify `null`. + } + export function exec(command: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function exec(command: string, options: ExecOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.exec("tsc", {encoding: null as string}, (err, stdout, stderr) => {}); + export function exec(command: string, options: ExecOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function exec(command: string, options: ExecOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; + export interface ExecFileOptions { + cwd?: string; + env?: any; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { + encoding: BufferEncoding; + } + export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { + encoding: string; // specify `null`. + } + export function execFile(file: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", ["foo"], {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export interface ExecOptions { - cwd?: string; - env?: any; - shell?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - uid?: number; - gid?: number; - } + export interface ForkOptions { + cwd?: string; + env?: any; + execPath?: string; + execArgv?: string[]; + silent?: boolean; + stdio?: any[]; + uid?: number; + gid?: number; + } + export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; - export interface ExecOptionsWithStringEncoding extends ExecOptions { - encoding: BufferEncoding; - } + export interface SpawnSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + shell?: boolean | string; + } + export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { + encoding: BufferEncoding; + } + export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { + encoding: string; // specify `null`. + } + export interface SpawnSyncReturns { + pid: number; + output: string[]; + stdout: T; + stderr: T; + status: number; + signal: string; + error: Error; + } + export function spawnSync(command: string): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; - export interface ExecOptionsWithBufferEncoding extends ExecOptions { - encoding: string | null; // specify `null`. - } + export interface ExecSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + shell?: string; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { + encoding: BufferEncoding; + } + export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { + encoding: string; // specify `null`. + } + export function execSync(command: string): Buffer; + export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; + export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; + export function execSync(command: string, options?: ExecSyncOptions): Buffer; - // no `options` definitely means stdout/stderr are `string`. - export function exec(command: string, callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - - // `options` with `"buffer"` or `null` for `encoding` means stdout/stderr are definitely `Buffer`. - export function exec(command: string, options: { encoding: "buffer" | null } & ExecOptions, callback?: (error: Error | null, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - - // `options` with well known `encoding` means stdout/stderr are definitely `string`. - export function exec(command: string, options: { encoding: BufferEncoding } & ExecOptions, callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - - // `options` with an `encoding` whose type is `string` means stdout/stderr could either be `Buffer` or `string`. - // There is no guarantee the `encoding` is unknown as `string` is a superset of `BufferEncoding`. - export function exec(command: string, options: { encoding: string } & ExecOptions, callback?: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; - - // `options` without an `encoding` means stdout/stderr are definitely `string`. - export function exec(command: string, options: ExecOptions, callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - - // fallback if nothing else matches. Worst case is always `string | Buffer`. - export function exec(command: string, options: ({ encoding?: string | null } & ExecOptions) | undefined | null, callback?: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace exec { - export function __promisify__(command: string): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(command: string, options: { encoding: "buffer" | null } & ExecOptions): Promise<{ stdout: Buffer, stderr: Buffer }>; - export function __promisify__(command: string, options: { encoding: BufferEncoding } & ExecOptions): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(command: string, options: ExecOptions): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(command: string, options?: ({ encoding?: string | null } & ExecOptions) | null): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; - } - - export interface ExecFileOptions { - cwd?: string; - env?: any; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - uid?: number; - gid?: number; - windowsVerbatimArguments?: boolean; - } - export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { - encoding: BufferEncoding; - } - export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { - encoding: 'buffer' | null; - } - export interface ExecFileOptionsWithOtherEncoding extends ExecFileOptions { - encoding: string; - } - - export function execFile(file: string): ChildProcess; - export function execFile(file: string, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): ChildProcess; - - // no `options` definitely means stdout/stderr are `string`. - export function execFile(file: string, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - - // `options` with `"buffer"` or `null` for `encoding` means stdout/stderr are definitely `Buffer`. - export function execFile(file: string, options: ExecFileOptionsWithBufferEncoding, callback: (error: Error | null, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithBufferEncoding, callback: (error: Error | null, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - - // `options` with well known `encoding` means stdout/stderr are definitely `string`. - export function execFile(file: string, options: ExecFileOptionsWithStringEncoding, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithStringEncoding, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - - // `options` with an `encoding` whose type is `string` means stdout/stderr could either be `Buffer` or `string`. - // There is no guarantee the `encoding` is unknown as `string` is a superset of `BufferEncoding`. - export function execFile(file: string, options: ExecFileOptionsWithOtherEncoding, callback: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithOtherEncoding, callback: (error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess; - - // `options` without an `encoding` means stdout/stderr are definitely `string`. - export function execFile(file: string, options: ExecFileOptions, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null, options: ExecFileOptions, callback: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess; - - // fallback if nothing else matches. Worst case is always `string | Buffer`. - export function execFile(file: string, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null, callback: ((error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void) | undefined | null): ChildProcess; - export function execFile(file: string, args: string[] | undefined | null, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null, callback: ((error: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void) | undefined | null): ChildProcess; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace execFile { - export function __promisify__(file: string): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(file: string, args: string[] | undefined | null): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(file: string, options: ExecFileOptionsWithBufferEncoding): Promise<{ stdout: Buffer, stderr: Buffer }>; - export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithBufferEncoding): Promise<{ stdout: Buffer, stderr: Buffer }>; - export function __promisify__(file: string, options: ExecFileOptionsWithStringEncoding): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithStringEncoding): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(file: string, options: ExecFileOptionsWithOtherEncoding): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; - export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptionsWithOtherEncoding): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; - export function __promisify__(file: string, options: ExecFileOptions): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(file: string, args: string[] | undefined | null, options: ExecFileOptions): Promise<{ stdout: string, stderr: string }>; - export function __promisify__(file: string, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; - export function __promisify__(file: string, args: string[] | undefined | null, options: ({ encoding?: string | null } & ExecFileOptions) | undefined | null): Promise<{ stdout: string | Buffer, stderr: string | Buffer }>; - } - - export interface ForkOptions { - cwd?: string; - env?: any; - execPath?: string; - execArgv?: string[]; - silent?: boolean; - stdio?: any[]; - uid?: number; - gid?: number; - windowsVerbatimArguments?: boolean; - } - export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; - - export interface SpawnSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - shell?: boolean | string; - windowsVerbatimArguments?: boolean; - } - export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { - encoding: BufferEncoding; - } - export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { - encoding: string; // specify `null`. - } - export interface SpawnSyncReturns { - pid: number; - output: string[]; - stdout: T; - stderr: T; - status: number; - signal: string; - error: Error; - } - export function spawnSync(command: string): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; - - export interface ExecSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - shell?: string; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - } - export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { - encoding: BufferEncoding; - } - export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { - encoding: string; // specify `null`. - } - export function execSync(command: string): Buffer; - export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; - export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; - export function execSync(command: string, options?: ExecSyncOptions): Buffer; - - export interface ExecFileSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - } - export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { - encoding: BufferEncoding; - } - export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { - encoding: string; // specify `null`. - } - export function execFileSync(command: string): Buffer; - export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; - export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; - export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; + export interface ExecFileSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { + encoding: BufferEncoding; + } + export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { + encoding: string; // specify `null`. + } + export function execFileSync(command: string): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; } declare module "url" { - import { ParsedUrlQuery } from 'querystring'; + export interface Url { + href?: string; + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: string | any; + slashes?: boolean; + hash?: string; + path?: string; + } - export interface UrlObjectCommon { - auth?: string; - hash?: string; - host?: string; - hostname?: string; - href?: string; - path?: string; - pathname?: string; - protocol?: string; - search?: string; - slashes?: boolean; - } + export interface UrlObject { + protocol?: string; + slashes?: boolean; + auth?: string; + host?: string; + hostname?: string; + port?: string | number; + pathname?: string; + search?: string; + query?: { [key: string]: any; }; + hash?: string; + } - // Input to `url.format` - export interface UrlObject extends UrlObjectCommon { - port?: string | number; - query?: string | null | { [key: string]: any }; - } + export function parse(urlStr: string, parseQueryString?: boolean, slashesDenoteHost?: boolean): Url; + export function format(URL: URL, options?: URLFormatOptions): string; + export function format(urlObject: UrlObject): string; + export function resolve(from: string, to: string): string; - // Output of `url.parse` - export interface Url extends UrlObjectCommon { - port?: string; - query?: string | null | ParsedUrlQuery; - } + export interface URLFormatOptions { + auth?: boolean; + fragment?: boolean; + search?: boolean; + unicode?: boolean; + } - export interface UrlWithParsedQuery extends Url { - query: ParsedUrlQuery; - } + export class URLSearchParams implements Iterable { + constructor(init?: URLSearchParams | string | { [key: string]: string | string[] } | Iterable); + append(name: string, value: string): void; + delete(name: string): void; + entries(): Iterator; + forEach(callback: (value: string, name: string) => void): void; + get(name: string): string | null; + getAll(name: string): string[]; + has(name: string): boolean; + keys(): Iterator; + set(name: string, value: string): void; + sort(): void; + toString(): string; + values(): Iterator; + [Symbol.iterator](): Iterator; + } - export interface UrlWithStringQuery extends Url { - query: string | null; - } - - export function parse(urlStr: string): UrlWithStringQuery; - export function parse(urlStr: string, parseQueryString: false | undefined, slashesDenoteHost?: boolean): UrlWithStringQuery; - export function parse(urlStr: string, parseQueryString: true, slashesDenoteHost?: boolean): UrlWithParsedQuery; - export function parse(urlStr: string, parseQueryString: boolean, slashesDenoteHost?: boolean): Url; - - export function format(URL: URL, options?: URLFormatOptions): string; - export function format(urlObject: UrlObject | string): string; - export function resolve(from: string, to: string): string; - - export interface URLFormatOptions { - auth?: boolean; - fragment?: boolean; - search?: boolean; - unicode?: boolean; - } - - export class URLSearchParams implements Iterable<[string, string]> { - constructor(init?: URLSearchParams | string | { [key: string]: string | string[] | undefined } | Iterable<[string, string]> | Array<[string, string]>); - append(name: string, value: string): void; - delete(name: string): void; - entries(): IterableIterator<[string, string]>; - forEach(callback: (value: string, name: string) => void): void; - get(name: string): string | null; - getAll(name: string): string[]; - has(name: string): boolean; - keys(): IterableIterator; - set(name: string, value: string): void; - sort(): void; - toString(): string; - values(): IterableIterator; - [Symbol.iterator](): IterableIterator<[string, string]>; - } - - export class URL { - constructor(input: string, base?: string | URL); - hash: string; - host: string; - hostname: string; - href: string; - readonly origin: string; - password: string; - pathname: string; - port: string; - protocol: string; - search: string; - readonly searchParams: URLSearchParams; - username: string; - toString(): string; - toJSON(): string; - } + export class URL { + constructor(input: string, base?: string | URL); + hash: string; + host: string; + hostname: string; + href: string; + readonly origin: string; + password: string; + pathname: string; + port: string; + protocol: string; + search: string; + readonly searchParams: URLSearchParams; + username: string; + toString(): string; + toJSON(): string; + } } declare module "dns" { - // Supported getaddrinfo flags. - export const ADDRCONFIG: number; - export const V4MAPPED: number; + // Supported getaddrinfo flags. + export const ADDRCONFIG: number; + export const V4MAPPED: number; - export interface LookupOptions { - family?: number; - hints?: number; - all?: boolean; - } + export interface LookupOptions { + family?: number; + hints?: number; + all?: boolean; + } - export interface LookupOneOptions extends LookupOptions { - all?: false; - } + export interface LookupOneOptions extends LookupOptions { + all?: false; + } - export interface LookupAllOptions extends LookupOptions { - all: true; - } + export interface LookupAllOptions extends LookupOptions { + all: true; + } - export interface LookupAddress { - address: string; - family: number; - } + export interface LookupAddress { + address: string; + family: number; + } - export function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; - export function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; - export function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException, addresses: LookupAddress[]) => void): void; - export function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException, address: string | LookupAddress[], family: number) => void): void; - export function lookup(hostname: string, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; + export function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; + export function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; + export function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException, addresses: LookupAddress[]) => void): void; + export function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException, address: string | LookupAddress[], family: number) => void): void; + export function lookup(hostname: string, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void): void; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace lookup { - export function __promisify__(hostname: string, options: LookupAllOptions): Promise<{ address: LookupAddress[] }>; - export function __promisify__(hostname: string, options?: LookupOneOptions | number): Promise<{ address: string, family: number }>; - export function __promisify__(hostname: string, options?: LookupOptions | number): Promise<{ address: string | LookupAddress[], family?: number }>; - } + export interface ResolveOptions { + ttl: boolean; + } - export interface ResolveOptions { - ttl: boolean; - } + export interface ResolveWithTtlOptions extends ResolveOptions { + ttl: true; + } - export interface ResolveWithTtlOptions extends ResolveOptions { - ttl: true; - } + export interface RecordWithTtl { + address: string; + ttl: number; + } - export interface RecordWithTtl { - address: string; - ttl: number; - } + export interface MxRecord { + priority: number; + exchange: string; + } - export interface MxRecord { - priority: number; - exchange: string; - } + export interface NaptrRecord { + flags: string; + service: string; + regexp: string; + replacement: string; + order: number; + preference: number; + } - export interface NaptrRecord { - flags: string; - service: string; - regexp: string; - replacement: string; - order: number; - preference: number; - } + export interface SoaRecord { + nsname: string; + hostmaster: string; + serial: number; + refresh: number; + retry: number; + expire: number; + minttl: number; + } - export interface SoaRecord { - nsname: string; - hostmaster: string; - serial: number; - refresh: number; - retry: number; - expire: number; - minttl: number; - } + export interface SrvRecord { + priority: number; + weight: number; + port: number; + name: string; + } - export interface SrvRecord { - priority: number; - weight: number; - port: number; - name: string; - } + export function resolve(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "A", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "AAAA", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "CNAME", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "MX", callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; + export function resolve(hostname: string, rrtype: "NAPTR", callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; + export function resolve(hostname: string, rrtype: "NS", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "PTR", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve(hostname: string, rrtype: "SOA", callback: (err: NodeJS.ErrnoException, addresses: SoaRecord) => void): void; + export function resolve(hostname: string, rrtype: "SRV", callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; + export function resolve(hostname: string, rrtype: "TXT", callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; + export function resolve(hostname: string, rrtype: string, callback: (err: NodeJS.ErrnoException, addresses: string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][]) => void): void; - export function resolve(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "A", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "AAAA", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "CNAME", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "MX", callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; - export function resolve(hostname: string, rrtype: "NAPTR", callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; - export function resolve(hostname: string, rrtype: "NS", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "PTR", callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve(hostname: string, rrtype: "SOA", callback: (err: NodeJS.ErrnoException, addresses: SoaRecord) => void): void; - export function resolve(hostname: string, rrtype: "SRV", callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; - export function resolve(hostname: string, rrtype: "TXT", callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; - export function resolve(hostname: string, rrtype: string, callback: (err: NodeJS.ErrnoException, addresses: string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][]) => void): void; + export function resolve4(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve4(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; + export function resolve4(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace resolve { - export function __promisify__(hostname: string, rrtype?: "A" | "AAAA" | "CNAME" | "NS" | "PTR"): Promise; - export function __promisify__(hostname: string, rrtype: "MX"): Promise; - export function __promisify__(hostname: string, rrtype: "NAPTR"): Promise; - export function __promisify__(hostname: string, rrtype: "SOA"): Promise; - export function __promisify__(hostname: string, rrtype: "SRV"): Promise; - export function __promisify__(hostname: string, rrtype: "TXT"): Promise; - export function __promisify__(hostname: string, rrtype?: string): Promise; - } + export function resolve6(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolve6(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; + export function resolve6(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; - export function resolve4(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve4(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; - export function resolve4(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; + export function resolveCname(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolveMx(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; + export function resolveNaptr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; + export function resolveNs(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolvePtr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; + export function resolveSoa(hostname: string, callback: (err: NodeJS.ErrnoException, address: SoaRecord) => void): void; + export function resolveSrv(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; + export function resolveTxt(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace resolve4 { - export function __promisify__(hostname: string): Promise; - export function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise; - export function __promisify__(hostname: string, options?: ResolveOptions): Promise; - } + export function reverse(ip: string, callback: (err: NodeJS.ErrnoException, hostnames: string[]) => void): void; + export function setServers(servers: string[]): void; - export function resolve6(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolve6(hostname: string, options: ResolveWithTtlOptions, callback: (err: NodeJS.ErrnoException, addresses: RecordWithTtl[]) => void): void; - export function resolve6(hostname: string, options: ResolveOptions, callback: (err: NodeJS.ErrnoException, addresses: string[] | RecordWithTtl[]) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace resolve6 { - export function __promisify__(hostname: string): Promise; - export function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise; - export function __promisify__(hostname: string, options?: ResolveOptions): Promise; - } - - export function resolveCname(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolveMx(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: MxRecord[]) => void): void; - export function resolveNaptr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: NaptrRecord[]) => void): void; - export function resolveNs(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolvePtr(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[]) => void): void; - export function resolveSoa(hostname: string, callback: (err: NodeJS.ErrnoException, address: SoaRecord) => void): void; - export function resolveSrv(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: SrvRecord[]) => void): void; - export function resolveTxt(hostname: string, callback: (err: NodeJS.ErrnoException, addresses: string[][]) => void): void; - - export function reverse(ip: string, callback: (err: NodeJS.ErrnoException, hostnames: string[]) => void): void; - export function setServers(servers: string[]): void; - - // Error codes - export var NODATA: string; - export var FORMERR: string; - export var SERVFAIL: string; - export var NOTFOUND: string; - export var NOTIMP: string; - export var REFUSED: string; - export var BADQUERY: string; - export var BADNAME: string; - export var BADFAMILY: string; - export var BADRESP: string; - export var CONNREFUSED: string; - export var TIMEOUT: string; - export var EOF: string; - export var FILE: string; - export var NOMEM: string; - export var DESTRUCTION: string; - export var BADSTR: string; - export var BADFLAGS: string; - export var NONAME: string; - export var BADHINTS: string; - export var NOTINITIALIZED: string; - export var LOADIPHLPAPI: string; - export var ADDRGETNETWORKPARAMS: string; - export var CANCELLED: string; + //Error codes + export var NODATA: string; + export var FORMERR: string; + export var SERVFAIL: string; + export var NOTFOUND: string; + export var NOTIMP: string; + export var REFUSED: string; + export var BADQUERY: string; + export var BADNAME: string; + export var BADFAMILY: string; + export var BADRESP: string; + export var CONNREFUSED: string; + export var TIMEOUT: string; + export var EOF: string; + export var FILE: string; + export var NOMEM: string; + export var DESTRUCTION: string; + export var BADSTR: string; + export var BADFLAGS: string; + export var NONAME: string; + export var BADHINTS: string; + export var NOTINITIALIZED: string; + export var LOADIPHLPAPI: string; + export var ADDRGETNETWORKPARAMS: string; + export var CANCELLED: string; } declare module "net" { - import * as stream from "stream"; - import * as events from "events"; - import * as dns from "dns"; + import * as stream from "stream"; + import * as events from "events"; - type LookupFunction = (hostname: string, options: dns.LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void) => void; + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; - export interface SocketConstructorOpts { - fd?: number; - allowHalfOpen?: boolean; - readable?: boolean; - writable?: boolean; - } + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): this; + write(data: any, encoding?: string, callback?: Function): void; + destroy(err?: any): void; + pause(): this; + resume(): this; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; - export interface TcpSocketConnectOpts { - port: number; - host?: string; - localAddress?: string; - localPort?: number; - hints?: number; - family?: number; - lookup?: LookupFunction; - } + remoteAddress: string; + remoteFamily: string; + remotePort: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + connecting: boolean; + destroyed: boolean; - export interface IpcSocketConnectOpts { - path: string; - } - - export type SocketConnectOpts = TcpSocketConnectOpts | IpcSocketConnectOpts; - - export class Socket extends stream.Duplex { - constructor(options?: SocketConstructorOpts); - - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - write(data: any, encoding?: string, callback?: Function): void; - - connect(options: SocketConnectOpts, connectionListener?: Function): this; - connect(port: number, host: string, connectionListener?: Function): this; - connect(port: number, connectionListener?: Function): this; - connect(path: string, connectionListener?: Function): this; - - bufferSize: number; - setEncoding(encoding?: string): this; - destroy(err?: any): void; - pause(): this; - resume(): this; - setTimeout(timeout: number, callback?: Function): this; - setNoDelay(noDelay?: boolean): this; - setKeepAlive(enable?: boolean, initialDelay?: number): this; - address(): { port: number; family: string; address: string; }; - unref(): void; - ref(): void; - - remoteAddress?: string; - remoteFamily?: string; - remotePort?: number; - localAddress: string; - localPort: number; - bytesRead: number; - bytesWritten: number; - connecting: boolean; - destroyed: boolean; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; /** * events.EventEmitter @@ -2640,97 +2137,97 @@ declare module "net" { * 7. lookup * 8. timeout */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: (had_error: boolean) => void): this; - addListener(event: "connect", listener: () => void): this; - addListener(event: "data", listener: (data: Buffer) => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "end", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - addListener(event: "timeout", listener: () => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: (had_error: boolean) => void): this; + addListener(event: "connect", listener: () => void): this; + addListener(event: "data", listener: (data: Buffer) => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "end", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + addListener(event: "timeout", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close", had_error: boolean): boolean; - emit(event: "connect"): boolean; - emit(event: "data", data: Buffer): boolean; - emit(event: "drain"): boolean; - emit(event: "end"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "lookup", err: Error, address: string, family: string | number, host: string): boolean; - emit(event: "timeout"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close", had_error: boolean): boolean; + emit(event: "connect"): boolean; + emit(event: "data", data: Buffer): boolean; + emit(event: "drain"): boolean; + emit(event: "end"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "lookup", err: Error, address: string, family: string | number, host: string): boolean; + emit(event: "timeout"): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: (had_error: boolean) => void): this; - on(event: "connect", listener: () => void): this; - on(event: "data", listener: (data: Buffer) => void): this; - on(event: "drain", listener: () => void): this; - on(event: "end", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - on(event: "timeout", listener: () => void): this; + on(event: string, listener: Function): this; + on(event: "close", listener: (had_error: boolean) => void): this; + on(event: "connect", listener: () => void): this; + on(event: "data", listener: (data: Buffer) => void): this; + on(event: "drain", listener: () => void): this; + on(event: "end", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + on(event: "timeout", listener: () => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: (had_error: boolean) => void): this; - once(event: "connect", listener: () => void): this; - once(event: "data", listener: (data: Buffer) => void): this; - once(event: "drain", listener: () => void): this; - once(event: "end", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - once(event: "timeout", listener: () => void): this; + once(event: string, listener: Function): this; + once(event: "close", listener: (had_error: boolean) => void): this; + once(event: "connect", listener: () => void): this; + once(event: "data", listener: (data: Buffer) => void): this; + once(event: "drain", listener: () => void): this; + once(event: "end", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + once(event: "timeout", listener: () => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: (had_error: boolean) => void): this; - prependListener(event: "connect", listener: () => void): this; - prependListener(event: "data", listener: (data: Buffer) => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "end", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - prependListener(event: "timeout", listener: () => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: (had_error: boolean) => void): this; + prependListener(event: "connect", listener: () => void): this; + prependListener(event: "data", listener: (data: Buffer) => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "end", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + prependListener(event: "timeout", listener: () => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: (had_error: boolean) => void): this; - prependOnceListener(event: "connect", listener: () => void): this; - prependOnceListener(event: "data", listener: (data: Buffer) => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "end", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; - prependOnceListener(event: "timeout", listener: () => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: (had_error: boolean) => void): this; + prependOnceListener(event: "connect", listener: () => void): this; + prependOnceListener(event: "data", listener: (data: Buffer) => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "end", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this; + prependOnceListener(event: "timeout", listener: () => void): this; + } - export interface ListenOptions { - port?: number; - host?: string; - backlog?: number; - path?: string; - exclusive?: boolean; - } + export var Socket: { + new(options?: { fd?: number; allowHalfOpen?: boolean; readable?: boolean; writable?: boolean; }): Socket; + }; - // https://github.com/nodejs/node/blob/master/lib/net.js - export class Server extends events.EventEmitter { - constructor(connectionListener?: (socket: Socket) => void); - constructor(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void); + export interface ListenOptions { + port?: number; + host?: string; + backlog?: number; + path?: string; + exclusive?: boolean; + } - listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this; - listen(port?: number, hostname?: string, listeningListener?: Function): this; - listen(port?: number, backlog?: number, listeningListener?: Function): this; - listen(port?: number, listeningListener?: Function): this; - listen(path: string, backlog?: number, listeningListener?: Function): this; - listen(path: string, listeningListener?: Function): this; - listen(options: ListenOptions, listeningListener?: Function): this; - listen(handle: any, backlog?: number, listeningListener?: Function): this; - listen(handle: any, listeningListener?: Function): this; - close(callback?: Function): this; - address(): { port: number; family: string; address: string; }; - getConnections(cb: (error: Error | null, count: number) => void): void; - ref(): this; - unref(): this; - maxConnections: number; - connections: number; - listening: boolean; + export interface Server extends events.EventEmitter { + listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function): Server; + listen(port: number, hostname?: string, listeningListener?: Function): Server; + listen(port: number, backlog?: number, listeningListener?: Function): Server; + listen(port: number, listeningListener?: Function): Server; + listen(path: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(options: ListenOptions, listeningListener?: Function): Server; + listen(handle: any, backlog?: number, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + getConnections(cb: (error: Error, count: number) => void): void; + ref(): Server; + unref(): Server; + maxConnections: number; + connections: number; + listening: boolean; /** * events.EventEmitter @@ -2739,123 +2236,101 @@ declare module "net" { * 3. error * 4. listening */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "connection", listener: (socket: Socket) => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "listening", listener: () => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "connection", listener: (socket: Socket) => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "listening", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "connection", socket: Socket): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "listening"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "connection", socket: Socket): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "listening"): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: () => void): this; - on(event: "connection", listener: (socket: Socket) => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "listening", listener: () => void): this; + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "connection", listener: (socket: Socket) => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "listening", listener: () => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: () => void): this; - once(event: "connection", listener: (socket: Socket) => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "listening", listener: () => void): this; + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "connection", listener: (socket: Socket) => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "listening", listener: () => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "connection", listener: (socket: Socket) => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "listening", listener: () => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "connection", listener: (socket: Socket) => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "listening", listener: () => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "connection", listener: (socket: Socket) => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "listening", listener: () => void): this; - } - - export interface TcpNetConnectOpts extends TcpSocketConnectOpts, SocketConstructorOpts { - timeout?: number; - } - - export interface IpcNetConnectOpts extends IpcSocketConnectOpts, SocketConstructorOpts { - timeout?: number; - } - - export type NetConnectOpts = TcpNetConnectOpts | IpcNetConnectOpts; - - export function createServer(connectionListener?: (socket: Socket) => void): Server; - export function createServer(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void): Server; - export function connect(options: NetConnectOpts, connectionListener?: Function): Socket; - export function connect(port: number, host?: string, connectionListener?: Function): Socket; - export function connect(path: string, connectionListener?: Function): Socket; - export function createConnection(options: NetConnectOpts, connectionListener?: Function): Socket; - export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; - export function createConnection(path: string, connectionListener?: Function): Socket; - export function isIP(input: string): number; - export function isIPv4(input: string): boolean; - export function isIPv6(input: string): boolean; + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "connection", listener: (socket: Socket) => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "listening", listener: () => void): this; + } + export function createServer(connectionListener?: (socket: Socket) => void): Server; + export function createServer(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void): Server; + export function connect(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; } declare module "dgram" { - import * as events from "events"; - import * as dns from "dns"; + import * as events from "events"; - interface RemoteInfo { - address: string; - family: string; - port: number; - } + interface RemoteInfo { + address: string; + family: string; + port: number; + } - interface AddressInfo { - address: string; - family: string; - port: number; - } + interface AddressInfo { + address: string; + family: string; + port: number; + } - interface BindOptions { - port: number; - address?: string; - exclusive?: boolean; - } + interface BindOptions { + port: number; + address?: string; + exclusive?: boolean; + } - type SocketType = "udp4" | "udp6"; + type SocketType = "udp4" | "udp6"; - interface SocketOptions { - type: SocketType; - reuseAddr?: boolean; - recvBufferSize?: number; - sendBufferSize?: number; - lookup?: (hostname: string, options: dns.LookupOneOptions, callback: (err: NodeJS.ErrnoException, address: string, family: number) => void) => void; - } + interface SocketOptions { + type: SocketType; + reuseAddr?: boolean; + } - export function createSocket(type: SocketType, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; - export function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + export function createSocket(type: SocketType, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + export function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; - export class Socket extends events.EventEmitter { - send(msg: Buffer | String | any[], port: number, address: string, callback?: (error: Error | null, bytes: number) => void): void; - send(msg: Buffer | String | any[], offset: number, length: number, port: number, address: string, callback?: (error: Error | null, bytes: number) => void): void; - bind(port?: number, address?: string, callback?: () => void): void; - bind(port?: number, callback?: () => void): void; - bind(callback?: () => void): void; - bind(options: BindOptions, callback?: Function): void; - close(callback?: () => void): void; - address(): AddressInfo; - setBroadcast(flag: boolean): void; - setTTL(ttl: number): void; - setMulticastTTL(ttl: number): void; - setMulticastInterface(multicastInterface: string): void; - setMulticastLoopback(flag: boolean): void; - addMembership(multicastAddress: string, multicastInterface?: string): void; - dropMembership(multicastAddress: string, multicastInterface?: string): void; - ref(): this; - unref(): this; - setRecvBufferSize(size: number): void; - setSendBufferSize(size: number): void; - getRecvBufferSize(): number; - getSendBufferSize(): number; + export interface Socket extends events.EventEmitter { + send(msg: Buffer | String | any[], port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + send(msg: Buffer | String | any[], offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port?: number, address?: string, callback?: () => void): void; + bind(options: BindOptions, callback?: Function): void; + close(callback?: () => void): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setTTL(ttl: number): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + ref(): this; + unref(): this; /** * events.EventEmitter @@ -2863,1736 +2338,586 @@ declare module "dgram" { * 2. error * 3. listening * 4. message - */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "listening", listener: () => void): this; - addListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + **/ + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "listening", listener: () => void): this; + addListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "listening"): boolean; - emit(event: "message", msg: Buffer, rinfo: AddressInfo): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "listening"): boolean; + emit(event: "message", msg: Buffer, rinfo: AddressInfo): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "listening", listener: () => void): this; - on(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "listening", listener: () => void): this; + on(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "listening", listener: () => void): this; - once(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "listening", listener: () => void): this; + once(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "listening", listener: () => void): this; - prependListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "listening", listener: () => void): this; + prependListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "listening", listener: () => void): this; - prependOnceListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "listening", listener: () => void): this; + prependOnceListener(event: "message", listener: (msg: Buffer, rinfo: AddressInfo) => void): this; + } } declare module "fs" { - import * as stream from "stream"; - import * as events from "events"; - import { URL } from "url"; + import * as stream from "stream"; + import * as events from "events"; - /** - * Valid types for path values in "fs". - */ - export type PathLike = string | Buffer | URL; + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } - export class Stats { - isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atimeMs: number; - mtimeMs: number; - ctimeMs: number; - birthtimeMs: number; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; - } - - export interface FSWatcher extends events.EventEmitter { - close(): void; + interface FSWatcher extends events.EventEmitter { + close(): void; /** * events.EventEmitter * 1. change * 2. error */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - addListener(event: "error", listener: (error: Error) => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + addListener(event: "error", listener: (error: Error) => void): this; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - on(event: "error", listener: (error: Error) => void): this; + on(event: string, listener: Function): this; + on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + on(event: "error", listener: (error: Error) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - once(event: "error", listener: (error: Error) => void): this; + once(event: string, listener: Function): this; + once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + once(event: "error", listener: (error: Error) => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - prependListener(event: "error", listener: (error: Error) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependListener(event: "error", listener: (error: Error) => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; - prependOnceListener(event: "error", listener: (error: Error) => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependOnceListener(event: "error", listener: (error: Error) => void): this; + } - export class ReadStream extends stream.Readable { - close(): void; - destroy(): void; - bytesRead: number; - path: string | Buffer; + export interface ReadStream extends stream.Readable { + close(): void; + destroy(): void; + bytesRead: number; + path: string | Buffer; /** * events.EventEmitter * 1. open * 2. close */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "open", listener: (fd: number) => void): this; - addListener(event: "close", listener: () => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "open", listener: (fd: number) => void): this; - on(event: "close", listener: () => void): this; + on(event: string, listener: Function): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "open", listener: (fd: number) => void): this; - once(event: "close", listener: () => void): this; + once(event: string, listener: Function): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "open", listener: (fd: number) => void): this; - prependListener(event: "close", listener: () => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "open", listener: (fd: number) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } - export class WriteStream extends stream.Writable { - close(): void; - bytesWritten: number; - path: string | Buffer; + export interface WriteStream extends stream.Writable { + close(): void; + bytesWritten: number; + path: string | Buffer; /** * events.EventEmitter * 1. open * 2. close */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "open", listener: (fd: number) => void): this; - addListener(event: "close", listener: () => void): this; + addListener(event: string, listener: Function): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; + + on(event: string, listener: Function): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } + + /** + * Asynchronous rename. + * @param oldPath + * @param newPath + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rename + * @param oldPath + * @param newPath + */ + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string | Buffer, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string | Buffer, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string | Buffer, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string | Buffer, uid: number, gid: number): void; + export function chmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string | Buffer, mode: number): void; + export function chmodSync(path: string | Buffer, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string | Buffer, mode: number): void; + export function lchmodSync(path: string | Buffer, mode: string): void; + export function stat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string | Buffer): Stats; + export function lstatSync(path: string | Buffer): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string | Buffer, dstpath: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string | Buffer, dstpath: string | Buffer): void; + export function symlink(srcpath: string | Buffer, dstpath: string | Buffer, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string | Buffer, dstpath: string | Buffer, type?: string): void; + export function readlink(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string | Buffer): string; + export function realpath(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string | Buffer, cache: { [path: string]: string }, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpathSync(path: string | Buffer, cache?: { [path: string]: string }): string; + /** + * Asynchronous unlink - deletes the file specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function unlink(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous unlink - deletes the file specified in {path} + * + * @param path + */ + export function unlinkSync(path: string | Buffer): void; + /** + * Asynchronous rmdir - removes the directory specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rmdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rmdir - removes the directory specified in {path} + * + * @param path + */ + export function rmdirSync(path: string | Buffer): void; + /** + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string | Buffer, mode?: number): void; + /** + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string | Buffer, mode?: string): void; + /** + * Asynchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @param callback The created folder path is passed as a string to the callback's second parameter. + */ + export function mkdtemp(prefix: string, callback?: (err: NodeJS.ErrnoException, folder: string) => void): void; + /** + * Synchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @returns Returns the created folder path. + */ + export function mkdtempSync(prefix: string): string; + export function readdir(path: string | Buffer, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdir(path: string | Buffer, options: string | {}, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string | Buffer, options?: string | {}): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string | Buffer, flags: string | number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + export function open(path: string | Buffer, flags: string | number, mode: number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + export function openSync(path: string | Buffer, flags: string | number, mode?: number): number; + export function utimes(path: string | Buffer, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string | Buffer, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string | Buffer, atime: number, mtime: number): void; + export function utimesSync(path: string | Buffer, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number | null, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number | null): number; + export function writeSync(fd: number, data: any, position?: number | null, enconding?: string): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number | null, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number | null): number; + /** + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, encoding: null, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, encoding: string | null, callback: (err: NodeJS.ErrnoException, data: string | Buffer) => void): void; + /** + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { encoding: null; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, options: { encoding: string | null; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string | Buffer) => void): void; + /** + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /** + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /** + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + */ + export function readFileSync(filename: string, encoding: null): Buffer; + export function readFileSync(filename: string, encoding: string): string; + export function readFileSync(filename: string, encoding: string | null): string | Buffer; + /** + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options: { encoding: null; flag?: string; }): Buffer; + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + export function readFileSync(filename: string, options: { encoding: string | null; flag?: string; }): string | Buffer; + /** + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string | number, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string | number, data: any, encoding: string, callback: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string | number, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string | number, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string | number, data: any, encoding: string): void; + export function writeFileSync(filename: string | number, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string | number, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, encoding: string, callback: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, encoding: string): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, encoding: string, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; recursive?: boolean; encoding?: string }, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; + export function exists(path: string | Buffer, callback?: (exists: boolean) => void): void; + export function existsSync(path: string | Buffer): boolean; + + export namespace constants { + // File Access Constants - on(event: string, listener: (...args: any[]) => void): this; - on(event: "open", listener: (fd: number) => void): this; - on(event: "close", listener: () => void): this; + /** Constant for fs.access(). File is visible to the calling process. */ + export const F_OK: number; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "open", listener: (fd: number) => void): this; - once(event: "close", listener: () => void): this; + /** Constant for fs.access(). File can be read by the calling process. */ + export const R_OK: number; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "open", listener: (fd: number) => void): this; - prependListener(event: "close", listener: () => void): this; + /** Constant for fs.access(). File can be written by the calling process. */ + export const W_OK: number; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "open", listener: (fd: number) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - } + /** Constant for fs.access(). File can be executed by the calling process. */ + export const X_OK: number; - /** - * Asynchronous rename(2) - Change the name or location of a file or directory. - * @param oldPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function rename(oldPath: PathLike, newPath: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace rename { - /** - * Asynchronous rename(2) - Change the name or location of a file or directory. - * @param oldPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function __promisify__(oldPath: PathLike, newPath: PathLike): Promise; - } - - /** - * Synchronous rename(2) - Change the name or location of a file or directory. - * @param oldPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function renameSync(oldPath: PathLike, newPath: PathLike): void; - - /** - * Asynchronous truncate(2) - Truncate a file to a specified length. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param len If not specified, defaults to `0`. - */ - export function truncate(path: PathLike, len: number | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; - - /** - * Asynchronous truncate(2) - Truncate a file to a specified length. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function truncate(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace truncate { - /** - * Asynchronous truncate(2) - Truncate a file to a specified length. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param len If not specified, defaults to `0`. - */ - export function __promisify__(path: PathLike, len?: number | null): Promise; - } - - /** - * Synchronous truncate(2) - Truncate a file to a specified length. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param len If not specified, defaults to `0`. - */ - export function truncateSync(path: PathLike, len?: number | null): void; - - /** - * Asynchronous ftruncate(2) - Truncate a file to a specified length. - * @param fd A file descriptor. - * @param len If not specified, defaults to `0`. - */ - export function ftruncate(fd: number, len: number | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; - - /** - * Asynchronous ftruncate(2) - Truncate a file to a specified length. - * @param fd A file descriptor. - */ - export function ftruncate(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace ftruncate { - /** - * Asynchronous ftruncate(2) - Truncate a file to a specified length. - * @param fd A file descriptor. - * @param len If not specified, defaults to `0`. - */ - export function __promisify__(fd: number, len?: number | null): Promise; - } - - /** - * Synchronous ftruncate(2) - Truncate a file to a specified length. - * @param fd A file descriptor. - * @param len If not specified, defaults to `0`. - */ - export function ftruncateSync(fd: number, len?: number | null): void; - - /** - * Asynchronous chown(2) - Change ownership of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function chown(path: PathLike, uid: number, gid: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace chown { - /** - * Asynchronous chown(2) - Change ownership of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function __promisify__(path: PathLike, uid: number, gid: number): Promise; - } - - /** - * Synchronous chown(2) - Change ownership of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function chownSync(path: PathLike, uid: number, gid: number): void; - - /** - * Asynchronous fchown(2) - Change ownership of a file. - * @param fd A file descriptor. - */ - export function fchown(fd: number, uid: number, gid: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace fchown { - /** - * Asynchronous fchown(2) - Change ownership of a file. - * @param fd A file descriptor. - */ - export function __promisify__(fd: number, uid: number, gid: number): Promise; - } - - /** - * Synchronous fchown(2) - Change ownership of a file. - * @param fd A file descriptor. - */ - export function fchownSync(fd: number, uid: number, gid: number): void; - - /** - * Asynchronous lchown(2) - Change ownership of a file. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function lchown(path: PathLike, uid: number, gid: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace lchown { - /** - * Asynchronous lchown(2) - Change ownership of a file. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function __promisify__(path: PathLike, uid: number, gid: number): Promise; - } - - /** - * Synchronous lchown(2) - Change ownership of a file. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function lchownSync(path: PathLike, uid: number, gid: number): void; - - /** - * Asynchronous chmod(2) - Change permissions of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function chmod(path: PathLike, mode: string | number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace chmod { - /** - * Asynchronous chmod(2) - Change permissions of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function __promisify__(path: PathLike, mode: string | number): Promise; - } - - /** - * Synchronous chmod(2) - Change permissions of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function chmodSync(path: PathLike, mode: string | number): void; - - /** - * Asynchronous fchmod(2) - Change permissions of a file. - * @param fd A file descriptor. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function fchmod(fd: number, mode: string | number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace fchmod { - /** - * Asynchronous fchmod(2) - Change permissions of a file. - * @param fd A file descriptor. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function __promisify__(fd: number, mode: string | number): Promise; - } - - /** - * Synchronous fchmod(2) - Change permissions of a file. - * @param fd A file descriptor. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function fchmodSync(fd: number, mode: string | number): void; - - /** - * Asynchronous lchmod(2) - Change permissions of a file. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function lchmod(path: PathLike, mode: string | number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace lchmod { - /** - * Asynchronous lchmod(2) - Change permissions of a file. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function __promisify__(path: PathLike, mode: string | number): Promise; - } - - /** - * Synchronous lchmod(2) - Change permissions of a file. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. - */ - export function lchmodSync(path: PathLike, mode: string | number): void; - - /** - * Asynchronous stat(2) - Get file status. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function stat(path: PathLike, callback: (err: NodeJS.ErrnoException, stats: Stats) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace stat { - /** - * Asynchronous stat(2) - Get file status. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function __promisify__(path: PathLike): Promise; - } - - /** - * Synchronous stat(2) - Get file status. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function statSync(path: PathLike): Stats; - - /** - * Asynchronous fstat(2) - Get file status. - * @param fd A file descriptor. - */ - export function fstat(fd: number, callback: (err: NodeJS.ErrnoException, stats: Stats) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace fstat { - /** - * Asynchronous fstat(2) - Get file status. - * @param fd A file descriptor. - */ - export function __promisify__(fd: number): Promise; - } - - /** - * Synchronous fstat(2) - Get file status. - * @param fd A file descriptor. - */ - export function fstatSync(fd: number): Stats; - - /** - * Asynchronous lstat(2) - Get file status. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function lstat(path: PathLike, callback: (err: NodeJS.ErrnoException, stats: Stats) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace lstat { - /** - * Asynchronous lstat(2) - Get file status. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function __promisify__(path: PathLike): Promise; - } - - /** - * Synchronous lstat(2) - Get file status. Does not dereference symbolic links. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function lstatSync(path: PathLike): Stats; - - /** - * Asynchronous link(2) - Create a new link (also known as a hard link) to an existing file. - * @param existingPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function link(existingPath: PathLike, newPath: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace link { - /** - * Asynchronous link(2) - Create a new link (also known as a hard link) to an existing file. - * @param existingPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function link(existingPath: PathLike, newPath: PathLike): Promise; - } - - /** - * Synchronous link(2) - Create a new link (also known as a hard link) to an existing file. - * @param existingPath A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param newPath A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function linkSync(existingPath: PathLike, newPath: PathLike): void; - - /** - * Asynchronous symlink(2) - Create a new symbolic link to an existing file. - * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. - * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. - * @param type May be set to `'dir'`, `'file'`, or `'junction'` (default is `'file'`) and is only available on Windows (ignored on other platforms). - * When using `'junction'`, the `target` argument will automatically be normalized to an absolute path. - */ - export function symlink(target: PathLike, path: PathLike, type: string | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; - - /** - * Asynchronous symlink(2) - Create a new symbolic link to an existing file. - * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. - * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. - */ - export function symlink(target: PathLike, path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace symlink { - /** - * Asynchronous symlink(2) - Create a new symbolic link to an existing file. - * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. - * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. - * @param type May be set to `'dir'`, `'file'`, or `'junction'` (default is `'file'`) and is only available on Windows (ignored on other platforms). - * When using `'junction'`, the `target` argument will automatically be normalized to an absolute path. - */ - export function __promisify__(target: PathLike, path: PathLike, type?: string | null): Promise; - } + // File Open Constants - /** - * Synchronous symlink(2) - Create a new symbolic link to an existing file. - * @param target A path to an existing file. If a URL is provided, it must use the `file:` protocol. - * @param path A path to the new symlink. If a URL is provided, it must use the `file:` protocol. - * @param type May be set to `'dir'`, `'file'`, or `'junction'` (default is `'file'`) and is only available on Windows (ignored on other platforms). - * When using `'junction'`, the `target` argument will automatically be normalized to an absolute path. - */ - export function symlinkSync(target: PathLike, path: PathLike, type?: string | null): void; + /** Constant for fs.open(). Flag indicating to open a file for read-only access. */ + export const O_RDONLY: number; - /** - * Asynchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readlink(path: PathLike, options: { encoding?: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, linkString: string) => void): void; + /** Constant for fs.open(). Flag indicating to open a file for write-only access. */ + export const O_WRONLY: number; - /** - * Asynchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readlink(path: PathLike, options: { encoding: "buffer" } | "buffer", callback: (err: NodeJS.ErrnoException, linkString: Buffer) => void): void; + /** Constant for fs.open(). Flag indicating to open a file for read-write access. */ + export const O_RDWR: number; - /** - * Asynchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readlink(path: PathLike, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, linkString: string | Buffer) => void): void; + /** Constant for fs.open(). Flag indicating to create the file if it does not already exist. */ + export const O_CREAT: number; - /** - * Asynchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function readlink(path: PathLike, callback: (err: NodeJS.ErrnoException, linkString: string) => void): void; + /** Constant for fs.open(). Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */ + export const O_EXCL: number; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace readlink { - /** - * Asynchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): Promise; + /** Constant for fs.open(). Flag indicating that if path identifies a terminal device, opening the path shall not cause that terminal to become the controlling terminal for the process (if the process does not already have one). */ + export const O_NOCTTY: number; - /** - * Asynchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options: { encoding: "buffer" } | "buffer"): Promise; + /** Constant for fs.open(). Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */ + export const O_TRUNC: number; - /** - * Asynchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options?: { encoding?: string | null } | string | null): Promise; - } + /** Constant for fs.open(). Flag indicating that data will be appended to the end of the file. */ + export const O_APPEND: number; - /** - * Synchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readlinkSync(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): string; + /** Constant for fs.open(). Flag indicating that the open should fail if the path is not a directory. */ + export const O_DIRECTORY: number; - /** - * Synchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readlinkSync(path: PathLike, options: { encoding: "buffer" } | "buffer"): Buffer; + /** Constant for fs.open(). Flag indicating reading accesses to the file system will no longer result in an update to the atime information associated with the file. This flag is available on Linux operating systems only. */ + export const O_NOATIME: number; - /** - * Synchronous readlink(2) - read value of a symbolic link. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readlinkSync(path: PathLike, options?: { encoding?: string | null } | string | null): string | Buffer; + /** Constant for fs.open(). Flag indicating that the open should fail if the path is a symbolic link. */ + export const O_NOFOLLOW: number; - /** - * Asynchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function realpath(path: PathLike, options: { encoding?: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => void): void; + /** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O. */ + export const O_SYNC: number; - /** - * Asynchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function realpath(path: PathLike, options: { encoding: "buffer" } | "buffer", callback: (err: NodeJS.ErrnoException, resolvedPath: Buffer) => void): void; + /** Constant for fs.open(). Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */ + export const O_SYMLINK: number; - /** - * Asynchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function realpath(path: PathLike, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, resolvedPath: string | Buffer) => void): void; + /** Constant for fs.open(). When set, an attempt will be made to minimize caching effects of file I/O. */ + export const O_DIRECT: number; - /** - * Asynchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function realpath(path: PathLike, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => void): void; + /** Constant for fs.open(). Flag indicating to open the file in nonblocking mode when possible. */ + export const O_NONBLOCK: number; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace realpath { - /** - * Asynchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): Promise; + // File Type Constants - /** - * Asynchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options: { encoding: "buffer" } | "buffer"): Promise; + /** Constant for fs.Stats mode property for determining a file's type. Bit mask used to extract the file type code. */ + export const S_IFMT: number; - /** - * Asynchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options?: { encoding?: string | null } | string | null): Promise; - } + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a regular file. */ + export const S_IFREG: number; - /** - * Synchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function realpathSync(path: PathLike, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): string; + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a directory. */ + export const S_IFDIR: number; - /** - * Synchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function realpathSync(path: PathLike, options: { encoding: "buffer" } | "buffer"): Buffer; + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a character-oriented device file. */ + export const S_IFCHR: number; - /** - * Synchronous realpath(3) - return the canonicalized absolute pathname. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function realpathSync(path: PathLike, options?: { encoding?: string | null } | string | null): string | Buffer; + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a block-oriented device file. */ + export const S_IFBLK: number; - /** - * Asynchronous unlink(2) - delete a name and possibly the file it refers to. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function unlink(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a FIFO/pipe. */ + export const S_IFIFO: number; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace unlink { - /** - * Asynchronous unlink(2) - delete a name and possibly the file it refers to. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function __promisify__(path: PathLike): Promise; - } + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a symbolic link. */ + export const S_IFLNK: number; - /** - * Synchronous unlink(2) - delete a name and possibly the file it refers to. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function unlinkSync(path: PathLike): void; + /** Constant for fs.Stats mode property for determining a file's type. File type constant for a socket. */ + export const S_IFSOCK: number; - /** - * Asynchronous rmdir(2) - delete a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function rmdir(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + // File Mode Constants - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace rmdir { - /** - * Asynchronous rmdir(2) - delete a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function __promisify__(path: PathLike): Promise; - } + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by owner. */ + export const S_IRWXU: number; - /** - * Synchronous rmdir(2) - delete a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function rmdirSync(path: PathLike): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by owner. */ + export const S_IRUSR: number; - /** - * Asynchronous mkdir(2) - create a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`. - */ - export function mkdir(path: PathLike, mode: number | string | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by owner. */ + export const S_IWUSR: number; - /** - * Asynchronous mkdir(2) - create a directory with a mode of `0o777`. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function mkdir(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by owner. */ + export const S_IXUSR: number; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace mkdir { - /** - * Asynchronous mkdir(2) - create a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`. - */ - export function __promisify__(path: PathLike, mode?: number | string | null): Promise; - } + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by group. */ + export const S_IRWXG: number; - /** - * Synchronous mkdir(2) - create a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`. - */ - export function mkdirSync(path: PathLike, mode?: number | string | null): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by group. */ + export const S_IRGRP: number; - /** - * Asynchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function mkdtemp(prefix: string, options: { encoding?: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, folder: string) => void): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by group. */ + export const S_IWGRP: number; - /** - * Asynchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function mkdtemp(prefix: string, options: "buffer" | { encoding: "buffer" }, callback: (err: NodeJS.ErrnoException, folder: Buffer) => void): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by group. */ + export const S_IXGRP: number; - /** - * Asynchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function mkdtemp(prefix: string, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, folder: string | Buffer) => void): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by others. */ + export const S_IRWXO: number; - /** - * Asynchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - */ - export function mkdtemp(prefix: string, callback: (err: NodeJS.ErrnoException, folder: string) => void): void; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by others. */ + export const S_IROTH: number; - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace mkdtemp { - /** - * Asynchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(prefix: string, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): Promise; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by others. */ + export const S_IWOTH: number; - /** - * Asynchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(prefix: string, options: { encoding: "buffer" } | "buffer"): Promise; - - /** - * Asynchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(prefix: string, options?: { encoding?: string | null } | string | null): Promise; - } - - /** - * Synchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function mkdtempSync(prefix: string, options?: { encoding?: BufferEncoding | null } | BufferEncoding | null): string; - - /** - * Synchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function mkdtempSync(prefix: string, options: { encoding: "buffer" } | "buffer"): Buffer; - - /** - * Synchronously creates a unique temporary directory. - * Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function mkdtempSync(prefix: string, options?: { encoding?: string | null } | string | null): string | Buffer; - - /** - * Asynchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readdir(path: PathLike, options: { encoding: BufferEncoding | null } | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; - - /** - * Asynchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readdir(path: PathLike, options: { encoding: "buffer" } | "buffer", callback: (err: NodeJS.ErrnoException, files: Buffer[]) => void): void; - - /** - * Asynchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readdir(path: PathLike, options: { encoding?: string | null } | string | undefined | null, callback: (err: NodeJS.ErrnoException, files: string[] | Buffer[]) => void): void; - - /** - * Asynchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function readdir(path: PathLike, callback: (err: NodeJS.ErrnoException, files: string[]) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace readdir { - /** - * Asynchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options?: { encoding: BufferEncoding | null } | BufferEncoding | null): Promise; - - /** - * Asynchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options: "buffer" | { encoding: "buffer" }): Promise; - - /** - * Asynchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function __promisify__(path: PathLike, options?: { encoding?: string | null } | string | null): Promise; - } - - /** - * Synchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readdirSync(path: PathLike, options?: { encoding: BufferEncoding | null } | BufferEncoding | null): string[]; - - /** - * Synchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readdirSync(path: PathLike, options: { encoding: "buffer" } | "buffer"): Buffer[]; - - /** - * Synchronous readdir(3) - read a directory. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used. - */ - export function readdirSync(path: PathLike, options?: { encoding?: string | null } | string | null): string[] | Buffer[]; - - /** - * Asynchronous close(2) - close a file descriptor. - * @param fd A file descriptor. - */ - export function close(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace close { - /** - * Asynchronous close(2) - close a file descriptor. - * @param fd A file descriptor. - */ - export function __promisify__(fd: number): Promise; - } - - /** - * Synchronous close(2) - close a file descriptor. - * @param fd A file descriptor. - */ - export function closeSync(fd: number): void; - - /** - * Asynchronous open(2) - open and possibly create a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not supplied, defaults to `0o666`. - */ - export function open(path: PathLike, flags: string | number, mode: string | number | undefined | null, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; - - /** - * Asynchronous open(2) - open and possibly create a file. If the file is created, its mode will be `0o666`. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - */ - export function open(path: PathLike, flags: string | number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace open { - /** - * Asynchronous open(2) - open and possibly create a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not supplied, defaults to `0o666`. - */ - export function __promisify__(path: PathLike, flags: string | number, mode?: string | number | null): Promise; - } - - /** - * Synchronous open(2) - open and possibly create a file, returning a file descriptor.. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param mode A file mode. If a string is passed, it is parsed as an octal integer. If not supplied, defaults to `0o666`. - */ - export function openSync(path: PathLike, flags: string | number, mode?: string | number | null): number; + /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by others. */ + export const S_IXOTH: number; + } - /** - * Asynchronously change file timestamps of the file referenced by the supplied path. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param atime The last access time. If a string is provided, it will be coerced to number. - * @param mtime The last modified time. If a string is provided, it will be coerced to number. - */ - export function utimes(path: PathLike, atime: string | number | Date, mtime: string | number | Date, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace utimes { - /** - * Asynchronously change file timestamps of the file referenced by the supplied path. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param atime The last access time. If a string is provided, it will be coerced to number. - * @param mtime The last modified time. If a string is provided, it will be coerced to number. - */ - export function __promisify__(path: PathLike, atime: string | number | Date, mtime: string | number | Date): Promise; - } - - /** - * Synchronously change file timestamps of the file referenced by the supplied path. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * @param atime The last access time. If a string is provided, it will be coerced to number. - * @param mtime The last modified time. If a string is provided, it will be coerced to number. - */ - export function utimesSync(path: PathLike, atime: string | number | Date, mtime: string | number | Date): void; - - /** - * Asynchronously change file timestamps of the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param atime The last access time. If a string is provided, it will be coerced to number. - * @param mtime The last modified time. If a string is provided, it will be coerced to number. - */ - export function futimes(fd: number, atime: string | number | Date, mtime: string | number | Date, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace futimes { - /** - * Asynchronously change file timestamps of the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param atime The last access time. If a string is provided, it will be coerced to number. - * @param mtime The last modified time. If a string is provided, it will be coerced to number. - */ - export function __promisify__(fd: number, atime: string | number | Date, mtime: string | number | Date): Promise; - } - - /** - * Synchronously change file timestamps of the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param atime The last access time. If a string is provided, it will be coerced to number. - * @param mtime The last modified time. If a string is provided, it will be coerced to number. - */ - export function futimesSync(fd: number, atime: string | number | Date, mtime: string | number | Date): void; - - /** - * Asynchronous fsync(2) - synchronize a file's in-core state with the underlying storage device. - * @param fd A file descriptor. - */ - export function fsync(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace fsync { - /** - * Asynchronous fsync(2) - synchronize a file's in-core state with the underlying storage device. - * @param fd A file descriptor. - */ - export function __promisify__(fd: number): Promise; - } - - /** - * Synchronous fsync(2) - synchronize a file's in-core state with the underlying storage device. - * @param fd A file descriptor. - */ - export function fsyncSync(fd: number): void; - - /** - * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. - * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. - * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. - */ - export function write(fd: number, buffer: TBuffer, offset: number | undefined | null, length: number | undefined | null, position: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; - - /** - * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. - * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. - */ - export function write(fd: number, buffer: TBuffer, offset: number | undefined | null, length: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; - - /** - * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. - */ - export function write(fd: number, buffer: TBuffer, offset: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; - - /** - * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - */ - export function write(fd: number, buffer: TBuffer, callback: (err: NodeJS.ErrnoException, written: number, buffer: TBuffer) => void): void; - - /** - * Asynchronously writes `string` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param string A string to write. If something other than a string is supplied it will be coerced to a string. - * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. - * @param encoding The expected string encoding. - */ - export function write(fd: number, string: any, position: number | undefined | null, encoding: string | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - - /** - * Asynchronously writes `string` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param string A string to write. If something other than a string is supplied it will be coerced to a string. - * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. - */ - export function write(fd: number, string: any, position: number | undefined | null, callback: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - - /** - * Asynchronously writes `string` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param string A string to write. If something other than a string is supplied it will be coerced to a string. - */ - export function write(fd: number, string: any, callback: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace write { - /** - * Asynchronously writes `buffer` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. - * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. - * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. - */ - export function __promisify__(fd: number, buffer?: TBuffer, offset?: number, length?: number, position?: number | null): Promise<{ bytesWritten: number, buffer: TBuffer }>; - - /** - * Asynchronously writes `string` to the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param string A string to write. If something other than a string is supplied it will be coerced to a string. - * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. - * @param encoding The expected string encoding. - */ - export function __promisify__(fd: number, string: any, position?: number | null, encoding?: string | null): Promise<{ bytesWritten: number, buffer: string }>; - } - - /** - * Synchronously writes `buffer` to the file referenced by the supplied file descriptor, returning the number of bytes written. - * @param fd A file descriptor. - * @param offset The part of the buffer to be written. If not supplied, defaults to `0`. - * @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`. - * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. - */ - export function writeSync(fd: number, buffer: Buffer | Uint8Array, offset?: number | null, length?: number | null, position?: number | null): number; - - /** - * Synchronously writes `string` to the file referenced by the supplied file descriptor, returning the number of bytes written. - * @param fd A file descriptor. - * @param string A string to write. If something other than a string is supplied it will be coerced to a string. - * @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position. - * @param encoding The expected string encoding. - */ - export function writeSync(fd: number, string: any, position?: number | null, encoding?: string | null): number; - - /** - * Asynchronously reads data from the file referenced by the supplied file descriptor. - * @param fd A file descriptor. - * @param buffer The buffer that the data will be written to. - * @param offset The offset in the buffer at which to start writing. - * @param length The number of bytes to read. - * @param position The offset from the beginning of the file from which data should be read. If `null`, data will be read from the current position. - */ - export function read(fd: number, buffer: TBuffer, offset: number, length: number, position: number | null, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: TBuffer) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace read { - /** - * @param fd A file descriptor. - * @param buffer The buffer that the data will be written to. - * @param offset The offset in the buffer at which to start writing. - * @param length The number of bytes to read. - * @param position The offset from the beginning of the file from which data should be read. If `null`, data will be read from the current position. - */ - export function __promisify__(fd: number, buffer: TBuffer, offset: number, length: number, position: number | null): Promise<{ bytesRead: number, buffer: TBuffer }>; - } - - /** - * Synchronously reads data from the file referenced by the supplied file descriptor, returning the number of bytes read. - * @param fd A file descriptor. - * @param buffer The buffer that the data will be written to. - * @param offset The offset in the buffer at which to start writing. - * @param length The number of bytes to read. - * @param position The offset from the beginning of the file from which data should be read. If `null`, data will be read from the current position. - */ - export function readSync(fd: number, buffer: Buffer | Uint8Array, offset: number, length: number, position: number | null): number; - - /** - * Asynchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options An object that may contain an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function readFile(path: PathLike | number, options: { encoding?: null; flag?: string; } | undefined | null, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - - /** - * Asynchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function readFile(path: PathLike | number, options: { encoding: string; flag?: string; } | string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - - /** - * Asynchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function readFile(path: PathLike | number, options: { encoding?: string | null; flag?: string; } | string | undefined | null, callback: (err: NodeJS.ErrnoException, data: string | Buffer) => void): void; - - /** - * Asynchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - */ - export function readFile(path: PathLike | number, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace readFile { - /** - * Asynchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options An object that may contain an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function __promisify__(path: PathLike | number, options?: { encoding?: null; flag?: string; } | null): Promise; - - /** - * Asynchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function __promisify__(path: PathLike | number, options: { encoding: string; flag?: string; } | string): Promise; - - /** - * Asynchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function __promisify__(path: PathLike | number, options?: { encoding?: string | null; flag?: string; } | string | null): Promise; - } - - /** - * Synchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options An object that may contain an optional flag. If a flag is not provided, it defaults to `'r'`. - */ - export function readFileSync(path: PathLike | number, options?: { encoding?: null; flag?: string; } | null): Buffer; - - /** - * Synchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function readFileSync(path: PathLike | number, options: { encoding: string; flag?: string; } | string): string; - - /** - * Synchronously reads the entire contents of a file. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. - * If a flag is not provided, it defaults to `'r'`. - */ - export function readFileSync(path: PathLike | number, options?: { encoding?: string | null; flag?: string; } | string | null): string | Buffer; - - /** - * Asynchronously writes data to a file, replacing the file if it already exists. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `mode` is not supplied, the default of `0o666` is used. - * If `mode` is a string, it is parsed as an octal integer. - * If `flag` is not supplied, the default of `'w'` is used. - */ - export function writeFile(path: PathLike | number, data: any, options: { encoding?: string | null; mode?: number | string; flag?: string; } | string | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; - - /** - * Asynchronously writes data to a file, replacing the file if it already exists. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - */ - export function writeFile(path: PathLike | number, data: any, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace writeFile { - /** - * Asynchronously writes data to a file, replacing the file if it already exists. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `mode` is not supplied, the default of `0o666` is used. - * If `mode` is a string, it is parsed as an octal integer. - * If `flag` is not supplied, the default of `'w'` is used. - */ - export function __promisify__(path: PathLike | number, data: any, options?: { encoding?: string | null; mode?: number | string; flag?: string; } | string | null): Promise; - } - - /** - * Synchronously writes data to a file, replacing the file if it already exists. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `mode` is not supplied, the default of `0o666` is used. - * If `mode` is a string, it is parsed as an octal integer. - * If `flag` is not supplied, the default of `'w'` is used. - */ - export function writeFileSync(path: PathLike | number, data: any, options?: { encoding?: string | null; mode?: number | string; flag?: string; } | string | null): void; - - /** - * Asynchronously append data to a file, creating the file if it does not exist. - * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `mode` is not supplied, the default of `0o666` is used. - * If `mode` is a string, it is parsed as an octal integer. - * If `flag` is not supplied, the default of `'a'` is used. - */ - export function appendFile(file: PathLike | number, data: any, options: { encoding?: string | null, mode?: string | number, flag?: string } | string | undefined | null, callback: (err: NodeJS.ErrnoException) => void): void; - - /** - * Asynchronously append data to a file, creating the file if it does not exist. - * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - */ - export function appendFile(file: PathLike | number, data: any, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace appendFile { - /** - * Asynchronously append data to a file, creating the file if it does not exist. - * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `mode` is not supplied, the default of `0o666` is used. - * If `mode` is a string, it is parsed as an octal integer. - * If `flag` is not supplied, the default of `'a'` is used. - */ - export function __promisify__(file: PathLike | number, data: any, options?: { encoding?: string | null, mode?: string | number, flag?: string } | string | null): Promise; - } - - /** - * Synchronously append data to a file, creating the file if it does not exist. - * @param file A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * If a file descriptor is provided, the underlying file will _not_ be closed automatically. - * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. - * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `mode` is not supplied, the default of `0o666` is used. - * If `mode` is a string, it is parsed as an octal integer. - * If `flag` is not supplied, the default of `'a'` is used. - */ - export function appendFileSync(file: PathLike | number, data: any, options?: { encoding?: string | null; mode?: number | string; flag?: string; } | string | null): void; - - /** - * Watch for changes on `filename`. The callback `listener` will be called each time the file is accessed. - */ - export function watchFile(filename: PathLike, options: { persistent?: boolean; interval?: number; } | undefined, listener: (curr: Stats, prev: Stats) => void): void; - - /** - * Watch for changes on `filename`. The callback `listener` will be called each time the file is accessed. - * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function watchFile(filename: PathLike, listener: (curr: Stats, prev: Stats) => void): void; - - /** - * Stop watching for changes on `filename`. - * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function unwatchFile(filename: PathLike, listener?: (curr: Stats, prev: Stats) => void): void; - - /** - * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. - * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `persistent` is not supplied, the default of `true` is used. - * If `recursive` is not supplied, the default of `false` is used. - */ - export function watch(filename: PathLike, options: { encoding?: BufferEncoding | null, persistent?: boolean, recursive?: boolean } | BufferEncoding | undefined | null, listener?: (event: string, filename: string) => void): FSWatcher; - - /** - * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. - * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `persistent` is not supplied, the default of `true` is used. - * If `recursive` is not supplied, the default of `false` is used. - */ - export function watch(filename: PathLike, options: { encoding: "buffer", persistent?: boolean, recursive?: boolean } | "buffer", listener?: (event: string, filename: Buffer) => void): FSWatcher; - - /** - * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. - * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - * @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options. - * If `encoding` is not supplied, the default of `'utf8'` is used. - * If `persistent` is not supplied, the default of `true` is used. - * If `recursive` is not supplied, the default of `false` is used. - */ - export function watch(filename: PathLike, options: { encoding?: string | null, persistent?: boolean, recursive?: boolean } | string | null, listener?: (event: string, filename: string | Buffer) => void): FSWatcher; - - /** - * Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`. - * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function watch(filename: PathLike, listener?: (event: string, filename: string) => any): FSWatcher; - - /** - * Asynchronously tests whether or not the given path exists by checking with the file system. - * @deprecated - * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function exists(path: PathLike, callback: (exists: boolean) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace exists { - /** - * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - function __promisify__(path: PathLike): Promise; - } - - /** - * Synchronously tests whether or not the given path exists by checking with the file system. - * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function existsSync(path: PathLike): boolean; - - export namespace constants { - // File Access Constants - - /** Constant for fs.access(). File is visible to the calling process. */ - export const F_OK: number; - - /** Constant for fs.access(). File can be read by the calling process. */ - export const R_OK: number; - - /** Constant for fs.access(). File can be written by the calling process. */ - export const W_OK: number; - - /** Constant for fs.access(). File can be executed by the calling process. */ - export const X_OK: number; - - // File Open Constants - - /** Constant for fs.open(). Flag indicating to open a file for read-only access. */ - export const O_RDONLY: number; - - /** Constant for fs.open(). Flag indicating to open a file for write-only access. */ - export const O_WRONLY: number; - - /** Constant for fs.open(). Flag indicating to open a file for read-write access. */ - export const O_RDWR: number; - - /** Constant for fs.open(). Flag indicating to create the file if it does not already exist. */ - export const O_CREAT: number; - - /** Constant for fs.open(). Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */ - export const O_EXCL: number; - - /** Constant for fs.open(). Flag indicating that if path identifies a terminal device, opening the path shall not cause that terminal to become the controlling terminal for the process (if the process does not already have one). */ - export const O_NOCTTY: number; - - /** Constant for fs.open(). Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */ - export const O_TRUNC: number; - - /** Constant for fs.open(). Flag indicating that data will be appended to the end of the file. */ - export const O_APPEND: number; - - /** Constant for fs.open(). Flag indicating that the open should fail if the path is not a directory. */ - export const O_DIRECTORY: number; - - /** Constant for fs.open(). Flag indicating reading accesses to the file system will no longer result in an update to the atime information associated with the file. This flag is available on Linux operating systems only. */ - export const O_NOATIME: number; - - /** Constant for fs.open(). Flag indicating that the open should fail if the path is a symbolic link. */ - export const O_NOFOLLOW: number; - - /** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O. */ - export const O_SYNC: number; - - /** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O with write operations waiting for data integrity. */ - export const O_DSYNC: number; - - /** Constant for fs.open(). Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */ - export const O_SYMLINK: number; - - /** Constant for fs.open(). When set, an attempt will be made to minimize caching effects of file I/O. */ - export const O_DIRECT: number; - - /** Constant for fs.open(). Flag indicating to open the file in nonblocking mode when possible. */ - export const O_NONBLOCK: number; - - // File Type Constants - - /** Constant for fs.Stats mode property for determining a file's type. Bit mask used to extract the file type code. */ - export const S_IFMT: number; - - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a regular file. */ - export const S_IFREG: number; - - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a directory. */ - export const S_IFDIR: number; - - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a character-oriented device file. */ - export const S_IFCHR: number; - - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a block-oriented device file. */ - export const S_IFBLK: number; - - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a FIFO/pipe. */ - export const S_IFIFO: number; - - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a symbolic link. */ - export const S_IFLNK: number; - - /** Constant for fs.Stats mode property for determining a file's type. File type constant for a socket. */ - export const S_IFSOCK: number; - - // File Mode Constants - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by owner. */ - export const S_IRWXU: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by owner. */ - export const S_IRUSR: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by owner. */ - export const S_IWUSR: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by owner. */ - export const S_IXUSR: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by group. */ - export const S_IRWXG: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by group. */ - export const S_IRGRP: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by group. */ - export const S_IWGRP: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by group. */ - export const S_IXGRP: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by others. */ - export const S_IRWXO: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by others. */ - export const S_IROTH: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by others. */ - export const S_IWOTH: number; - - /** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by others. */ - export const S_IXOTH: number; - - /** Constant for fs.copyFile. Flag indicating the destination file should not be overwritten if it already exists. */ - export const COPYFILE_EXCL: number; - } - - /** - * Asynchronously tests a user's permissions for the file specified by path. - * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function access(path: PathLike, mode: number | undefined, callback: (err: NodeJS.ErrnoException) => void): void; - - /** - * Asynchronously tests a user's permissions for the file specified by path. - * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function access(path: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace access { - /** - * Asynchronously tests a user's permissions for the file specified by path. - * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function __promisify__(path: PathLike, mode?: number): Promise; - } - - /** - * Synchronously tests a user's permissions for the file specified by path. - * @param path A path to a file or directory. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function accessSync(path: PathLike, mode?: number): void; - - /** - * Returns a new `ReadStream` object. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function createReadStream(path: PathLike, options?: string | { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - autoClose?: boolean; - start?: number; - end?: number; - highWaterMark?: number; - }): ReadStream; - - /** - * Returns a new `WriteStream` object. - * @param path A path to a file. If a URL is provided, it must use the `file:` protocol. - * URL support is _experimental_. - */ - export function createWriteStream(path: PathLike, options?: string | { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - autoClose?: boolean; - start?: number; - }): WriteStream; - - /** - * Asynchronous fdatasync(2) - synchronize a file's in-core state with storage device. - * @param fd A file descriptor. - */ - export function fdatasync(fd: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace fdatasync { - /** - * Asynchronous fdatasync(2) - synchronize a file's in-core state with storage device. - * @param fd A file descriptor. - */ - export function __promisify__(fd: number): Promise; - } - - /** - * Synchronous fdatasync(2) - synchronize a file's in-core state with storage device. - * @param fd A file descriptor. - */ - export function fdatasyncSync(fd: number): void; - - /** - * Asynchronously copies src to dest. By default, dest is overwritten if it already exists. - * No arguments other than a possible exception are given to the callback function. - * Node.js makes no guarantees about the atomicity of the copy operation. - * If an error occurs after the destination file has been opened for writing, Node.js will attempt - * to remove the destination. - * @param src A path to the source file. - * @param dest A path to the destination file. - */ - export function copyFile(src: PathLike, dest: PathLike, callback: (err: NodeJS.ErrnoException) => void): void; - /** - * Asynchronously copies src to dest. By default, dest is overwritten if it already exists. - * No arguments other than a possible exception are given to the callback function. - * Node.js makes no guarantees about the atomicity of the copy operation. - * If an error occurs after the destination file has been opened for writing, Node.js will attempt - * to remove the destination. - * @param src A path to the source file. - * @param dest A path to the destination file. - * @param flags An integer that specifies the behavior of the copy operation. The only supported flag is fs.constants.COPYFILE_EXCL, which causes the copy operation to fail if dest already exists. - */ - export function copyFile(src: PathLike, dest: PathLike, flags: number, callback: (err: NodeJS.ErrnoException) => void): void; - - // NOTE: This namespace provides design-time support for util.promisify. Exported members do not exist at runtime. - export namespace copyFile { - /** - * Asynchronously copies src to dest. By default, dest is overwritten if it already exists. - * No arguments other than a possible exception are given to the callback function. - * Node.js makes no guarantees about the atomicity of the copy operation. - * If an error occurs after the destination file has been opened for writing, Node.js will attempt - * to remove the destination. - * @param src A path to the source file. - * @param dest A path to the destination file. - * @param flags An optional integer that specifies the behavior of the copy operation. The only supported flag is fs.constants.COPYFILE_EXCL, which causes the copy operation to fail if dest already exists. - */ - export function __promisify__(src: PathLike, dst: PathLike, flags?: number): Promise; - } - - /** - * Synchronously copies src to dest. By default, dest is overwritten if it already exists. - * Node.js makes no guarantees about the atomicity of the copy operation. - * If an error occurs after the destination file has been opened for writing, Node.js will attempt - * to remove the destination. - * @param src A path to the source file. - * @param dest A path to the destination file. - * @param flags An optional integer that specifies the behavior of the copy operation. The only supported flag is fs.constants.COPYFILE_EXCL, which causes the copy operation to fail if dest already exists. - */ - export function copyFileSync(src: PathLike, dest: PathLike, flags?: number): void; + /** Tests a user's permissions for the file specified by path. */ + export function access(path: string | Buffer, callback: (err: NodeJS.ErrnoException) => void): void; + export function access(path: string | Buffer, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; + /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ + export function accessSync(path: string | Buffer, mode?: number): void; + export function createReadStream(path: string | Buffer, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + start?: number; + end?: number; + }): ReadStream; + export function createWriteStream(path: string | Buffer, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + start?: number; + }): WriteStream; + export function fdatasync(fd: number, callback: Function): void; + export function fdatasyncSync(fd: number): void; } declare module "path" { + /** * A parsed path object generated by path.parse() or consumed by path.format(). */ - export interface ParsedPath { + export interface ParsedPath { /** * The root of the path such as '/' or 'c:\' */ - root: string; + root: string; /** * The full directory path such as '/home/user/dir' or 'c:\path\dir' */ - dir: string; + dir: string; /** * The file name including extension (if any) such as 'index.html' */ - base: string; + base: string; /** * The file extension (if any) such as '.html' */ - ext: string; + ext: string; /** * The file name without extension (if any) such as 'index' */ - name: string; - } - export interface FormatInputPathObject { - /** - * The root of the path such as '/' or 'c:\' - */ - root?: string; - /** - * The full directory path such as '/home/user/dir' or 'c:\path\dir' - */ - dir?: string; - /** - * The file name including extension (if any) such as 'index.html' - */ - base?: string; - /** - * The file extension (if any) such as '.html' - */ - ext?: string; - /** - * The file name without extension (if any) such as 'index' - */ - name?: string; - } + name: string; + } /** * Normalize a string path, reducing '..' and '.' parts. @@ -4600,14 +2925,14 @@ declare module "path" { * * @param p string path to normalize. */ - export function normalize(p: string): string; + export function normalize(p: string): string; /** * Join all arguments together and normalize the resulting path. * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. * * @param paths paths to join. */ - export function join(...paths: string[]): string; + export function join(...paths: string[]): string; /** * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. * @@ -4617,24 +2942,27 @@ declare module "path" { * * @param pathSegments string paths to join. Non-string arguments are ignored. */ - export function resolve(...pathSegments: string[]): string; + export function resolve(...pathSegments: any[]): string; /** * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. * * @param path path to test. */ - export function isAbsolute(path: string): boolean; + export function isAbsolute(path: string): boolean; /** * Solve the relative path from {from} to {to}. * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. + * + * @param from + * @param to */ - export function relative(from: string, to: string): string; + export function relative(from: string, to: string): string; /** * Return the directory name of a path. Similar to the Unix dirname command. * * @param p the path to evaluate. */ - export function dirname(p: string): string; + export function dirname(p: string): string; /** * Return the last portion of a path. Similar to the Unix basename command. * Often used to extract the file name from a fully qualified path. @@ -4642,177 +2970,176 @@ declare module "path" { * @param p the path to evaluate. * @param ext optionally, an extension to remove from the result. */ - export function basename(p: string, ext?: string): string; + export function basename(p: string, ext?: string): string; /** * Return the extension of the path, from the last '.' to end of string in the last portion of the path. * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string * * @param p the path to evaluate. */ - export function extname(p: string): string; + export function extname(p: string): string; /** * The platform-specific file separator. '\\' or '/'. */ - export var sep: string; + export var sep: string; /** * The platform-specific file delimiter. ';' or ':'. */ - export var delimiter: string; + export var delimiter: string; /** * Returns an object from a path string - the opposite of format(). * * @param pathString path to evaluate. */ - export function parse(pathString: string): ParsedPath; + export function parse(pathString: string): ParsedPath; /** * Returns a path string from an object - the opposite of parse(). * * @param pathString path to evaluate. */ - export function format(pathObject: FormatInputPathObject): string; + export function format(pathObject: ParsedPath): string; - export module posix { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: FormatInputPathObject): string; - } + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } - export module win32 { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: FormatInputPathObject): string; - } + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } } declare module "string_decoder" { - export interface NodeStringDecoder { - write(buffer: Buffer): string; - end(buffer?: Buffer): string; - } - export var StringDecoder: { - new(encoding?: string): NodeStringDecoder; - }; + export interface NodeStringDecoder { + write(buffer: Buffer): string; + end(buffer?: Buffer): string; + } + export var StringDecoder: { + new(encoding?: string): NodeStringDecoder; + }; } declare module "tls" { - import * as crypto from "crypto"; - import * as dns from "dns"; - import * as net from "net"; - import * as stream from "stream"; + import * as crypto from "crypto"; + import * as net from "net"; + import * as stream from "stream"; - var CLIENT_RENEG_LIMIT: number; - var CLIENT_RENEG_WINDOW: number; + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; - export interface Certificate { + export interface Certificate { /** * Country code. */ - C: string; + C: string; /** * Street. */ - ST: string; + ST: string; /** * Locality. */ - L: string; + L: string; /** * Organization. */ - O: string; + O: string; /** * Organizational unit. */ - OU: string; + OU: string; /** * Common name. */ - CN: string; - } + CN: string; + } - export interface PeerCertificate { - subject: Certificate; - issuer: Certificate; - subjectaltname: string; - infoAccess: { [index: string]: string[] | undefined }; - modulus: string; - exponent: string; - valid_from: string; - valid_to: string; - fingerprint: string; - ext_key_usage: string[]; - serialNumber: string; - raw: Buffer; - } + export interface PeerCertificate { + subject: Certificate; + issuer: Certificate; + subjectaltname: string; + infoAccess: { [index: string]: string[] }; + modulus: string; + exponent: string; + valid_from: string; + valid_to: string; + fingerprint: string; + ext_key_usage: string[]; + serialNumber: string; + raw: Buffer; + } - export interface DetailedPeerCertificate extends PeerCertificate { - issuerCertificate: DetailedPeerCertificate; - } + export interface DetailedPeerCertificate extends PeerCertificate { + issuerCertificate: DetailedPeerCertificate; + } - export interface CipherNameAndProtocol { + export interface CipherNameAndProtocol { /** * The cipher name. */ - name: string; + name: string; /** * SSL/TLS protocol version. */ - version: string; - } + version: string; + } - export class TLSSocket extends net.Socket { + export class TLSSocket extends net.Socket { /** * Construct a new tls.TLSSocket object from an existing TCP socket. */ - constructor(socket: net.Socket, options?: { + constructor(socket: net.Socket, options?: { /** * An optional TLS context object from tls.createSecureContext() */ - secureContext?: SecureContext, + secureContext?: SecureContext, /** * If true the TLS socket will be instantiated in server-mode. * Defaults to false. */ - isServer?: boolean, + isServer?: boolean, /** * An optional net.Server instance. */ - server?: net.Server, + server?: net.Server, /** * If true the server will request a certificate from clients that * connect and attempt to verify that certificate. Defaults to * false. */ - requestCert?: boolean, + requestCert?: boolean, /** * If true the server will reject any connection which is not * authorized with the list of supplied CAs. This option only has an * effect if requestCert is true. Defaults to false. */ - rejectUnauthorized?: boolean, + rejectUnauthorized?: boolean, /** * An array of strings or a Buffer naming possible NPN protocols. * (Protocols should be ordered by their priority.) */ - NPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array, + NPNProtocols?: string[] | Buffer, /** * An array of strings or a Buffer naming possible ALPN protocols. * (Protocols should be ordered by their priority.) When the server @@ -4820,7 +3147,7 @@ declare module "tls" { * precedence over NPN and the server does not send an NPN extension * to the client. */ - ALPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array, + ALPNProtocols?: string[] | Buffer, /** * SNICallback(servername, cb) A function that will be * called if the client supports SNI TLS extension. Two arguments @@ -4830,73 +3157,99 @@ declare module "tls" { * SecureContext.) If SNICallback wasn't provided the default callback * with high-level API will be used (see below). */ - SNICallback?: (servername: string, cb: (err: Error | null, ctx: SecureContext) => void) => void, + SNICallback?: Function, /** * An optional Buffer instance containing a TLS session. */ - session?: Buffer, + session?: Buffer, /** * If true, specifies that the OCSP status request extension will be * added to the client hello and an 'OCSPResponse' event will be * emitted on the socket before establishing a secure communication */ - requestOCSP?: boolean - }); - + requestOCSP?: boolean + }); + /** + * Returns the bound address, the address family name and port of the underlying socket as reported by + * the operating system. + * @returns {any} - An object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }. + */ + address(): { port: number; family: string; address: string }; /** * A boolean that is true if the peer certificate was signed by one of the specified CAs, otherwise false. */ - authorized: boolean; + authorized: boolean; /** * The reason why the peer's certificate has not been verified. * This property becomes available only when tlsSocket.authorized === false. */ - authorizationError: Error; + authorizationError: Error; /** * Static boolean value, always true. * May be used to distinguish TLS sockets from regular ones. */ - encrypted: boolean; + encrypted: boolean; /** * Returns an object representing the cipher name and the SSL/TLS protocol version of the current connection. - * @returns Returns an object representing the cipher name + * @returns {CipherNameAndProtocol} - Returns an object representing the cipher name * and the SSL/TLS protocol version of the current connection. */ - getCipher(): CipherNameAndProtocol; + getCipher(): CipherNameAndProtocol; /** * Returns an object representing the peer's certificate. * The returned object has some properties corresponding to the field of the certificate. * If detailed argument is true the full chain with issuer property will be returned, * if false only the top certificate without issuer property. * If the peer does not provide a certificate, it returns null or an empty object. - * @param detailed - If true; the full chain with issuer property will be returned. - * @returns An object representing the peer's certificate. + * @param {boolean} detailed - If true; the full chain with issuer property will be returned. + * @returns {PeerCertificate | DetailedPeerCertificate} - An object representing the peer's certificate. */ - getPeerCertificate(detailed: true): DetailedPeerCertificate; - getPeerCertificate(detailed?: false): PeerCertificate; - getPeerCertificate(detailed?: boolean): PeerCertificate | DetailedPeerCertificate; + getPeerCertificate(detailed: true): DetailedPeerCertificate; + getPeerCertificate(detailed?: false): PeerCertificate; + getPeerCertificate(detailed?: boolean): PeerCertificate | DetailedPeerCertificate; /** * Could be used to speed up handshake establishment when reconnecting to the server. - * @returns ASN.1 encoded TLS session or undefined if none was negotiated. + * @returns {any} - ASN.1 encoded TLS session or undefined if none was negotiated. */ - getSession(): any; + getSession(): any; /** * NOTE: Works only with client TLS sockets. * Useful only for debugging, for session reuse provide session option to tls.connect(). - * @returns TLS session ticket or undefined if none was negotiated. + * @returns {any} - TLS session ticket or undefined if none was negotiated. */ - getTLSTicket(): any; + getTLSTicket(): any; + /** + * The string representation of the local IP address. + */ + localAddress: string; + /** + * The numeric representation of the local port. + */ + localPort: number; + /** + * The string representation of the remote IP address. + * For example, '74.125.127.100' or '2001:4860:a005::68'. + */ + remoteAddress: string; + /** + * The string representation of the remote IP family. 'IPv4' or 'IPv6'. + */ + remoteFamily: string; + /** + * The numeric representation of the remote port. For example, 443. + */ + remotePort: number; /** * Initiate TLS renegotiation process. * * NOTE: Can be used to request peer's certificate after the secure connection has been established. * ANOTHER NOTE: When running as the server, socket will be destroyed with an error after handshakeTimeout timeout. - * @param options - The options may contain the following fields: rejectUnauthorized, + * @param {TlsOptions} options - The options may contain the following fields: rejectUnauthorized, * requestCert (See tls.createServer() for details). - * @param callback - callback(err) will be executed with null as err, once the renegotiation + * @param {Function} callback - callback(err) will be executed with null as err, once the renegotiation * is successfully completed. */ - renegotiate(options: { rejectUnauthorized?: boolean, requestCert?: boolean }, callback: (err: Error | null) => void): any; + renegotiate(options: TlsOptions, callback: (err: Error) => any): any; /** * Set maximum TLS fragment size (default and maximum value is: 16384, minimum is: 512). * Smaller fragment size decreases buffering latency on the client: large fragments are buffered by @@ -4904,74 +3257,97 @@ declare module "tls" { * large fragments can span multiple roundtrips, and their processing can be delayed due to packet * loss or reordering. However, smaller fragments add extra TLS framing bytes and CPU overhead, * which may decrease overall server throughput. - * @param size - TLS fragment size (default and maximum value is: 16384, minimum is: 512). - * @returns Returns true on success, false otherwise. + * @param {number} size - TLS fragment size (default and maximum value is: 16384, minimum is: 512). + * @returns {boolean} - Returns true on success, false otherwise. */ - setMaxSendFragment(size: number): boolean; + setMaxSendFragment(size: number): boolean; /** * events.EventEmitter * 1. OCSPResponse * 2. secureConnect - */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; - addListener(event: "secureConnect", listener: () => void): this; + **/ + addListener(event: string, listener: Function): this; + addListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; + addListener(event: "secureConnect", listener: () => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "OCSPResponse", response: Buffer): boolean; - emit(event: "secureConnect"): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "OCSPResponse", response: Buffer): boolean; + emit(event: "secureConnect"): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "OCSPResponse", listener: (response: Buffer) => void): this; - on(event: "secureConnect", listener: () => void): this; + on(event: string, listener: Function): this; + on(event: "OCSPResponse", listener: (response: Buffer) => void): this; + on(event: "secureConnect", listener: () => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "OCSPResponse", listener: (response: Buffer) => void): this; - once(event: "secureConnect", listener: () => void): this; + once(event: string, listener: Function): this; + once(event: "OCSPResponse", listener: (response: Buffer) => void): this; + once(event: "secureConnect", listener: () => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; - prependListener(event: "secureConnect", listener: () => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; + prependListener(event: "secureConnect", listener: () => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; - prependOnceListener(event: "secureConnect", listener: () => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "OCSPResponse", listener: (response: Buffer) => void): this; + prependOnceListener(event: "secureConnect", listener: () => void): this; + } - export interface TlsOptions extends SecureContextOptions { - handshakeTimeout?: number; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; - ALPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; - SNICallback?: (servername: string, cb: (err: Error | null, ctx: SecureContext) => void) => void; - sessionTimeout?: number; - ticketKeys?: Buffer; - } + export interface TlsOptions { + host?: string; + port?: number; + pfx?: string | Buffer[]; + key?: string | string[] | Buffer | any[]; + passphrase?: string; + cert?: string | string[] | Buffer | Buffer[]; + ca?: string | string[] | Buffer | Buffer[]; + crl?: string | string[]; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: string[] | Buffer; + SNICallback?: (servername: string, cb: (err: Error, ctx: SecureContext) => any) => any; + ecdhCurve?: string; + dhparam?: string | Buffer; + handshakeTimeout?: number; + ALPNProtocols?: string[] | Buffer; + sessionTimeout?: number; + ticketKeys?: any; + sessionIdContext?: string; + secureProtocol?: string; + } - export interface ConnectionOptions extends SecureContextOptions { - host?: string; - port?: number; - path?: string; // Creates unix socket connection to path. If this option is specified, `host` and `port` are ignored. - socket?: net.Socket; // Establish secure connection on a given socket rather than creating a new socket - rejectUnauthorized?: boolean; // Defaults to true - NPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; - ALPNProtocols?: string[] | Buffer[] | Uint8Array[] | Buffer | Uint8Array; - checkServerIdentity?: typeof checkServerIdentity; - servername?: string; // SNI TLS Extension - session?: Buffer; - minDHSize?: number; - secureContext?: SecureContext; // If not provided, the entire ConnectionOptions object will be passed to tls.createSecureContext() - lookup?: net.LookupFunction; - } + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: string | Buffer + key?: string | string[] | Buffer | Buffer[]; + passphrase?: string; + cert?: string | string[] | Buffer | Buffer[]; + ca?: string | Buffer | (string | Buffer)[]; + rejectUnauthorized?: boolean; + NPNProtocols?: (string | Buffer)[]; + servername?: string; + path?: string; + ALPNProtocols?: (string | Buffer)[]; + checkServerIdentity?: (servername: string, cert: string | Buffer | (string | Buffer)[]) => any; + secureProtocol?: string; + secureContext?: Object; + session?: Buffer; + minDHSize?: number; + } - export class Server extends net.Server { - addContext(hostName: string, credentials: { - key: string; - cert: string; - ca: string; - }): void; + export interface Server extends net.Server { + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; /** * events.EventEmitter @@ -4980,2162 +3356,1022 @@ declare module "tls" { * 3. OCSPRequest * 4. resumeSession * 5. secureConnection - */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - addListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - addListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - addListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - addListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + **/ + addListener(event: string, listener: Function): this; + addListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + addListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + addListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + addListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + addListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "tlsClientError", err: Error, tlsSocket: TLSSocket): boolean; - emit(event: "newSession", sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void): boolean; - emit(event: "OCSPRequest", certificate: Buffer, issuer: Buffer, callback: Function): boolean; - emit(event: "resumeSession", sessionId: any, callback: (err: Error, sessionData: any) => void): boolean; - emit(event: "secureConnection", tlsSocket: TLSSocket): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "tlsClientError", err: Error, tlsSocket: TLSSocket): boolean; + emit(event: "newSession", sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void): boolean; + emit(event: "OCSPRequest", certificate: Buffer, issuer: Buffer, callback: Function): boolean; + emit(event: "resumeSession", sessionId: any, callback: (err: Error, sessionData: any) => void): boolean; + emit(event: "secureConnection", tlsSocket: TLSSocket): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - on(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - on(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - on(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - on(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + on(event: string, listener: Function): this; + on(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + on(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + on(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + on(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + on(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - once(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - once(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - once(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - once(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + once(event: string, listener: Function): this; + once(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + once(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + once(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + once(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + once(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - prependListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - prependListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - prependListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - prependListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + prependListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + prependListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + prependListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + prependListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; - prependOnceListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; - prependOnceListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; - prependOnceListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; - prependOnceListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; - } + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this; + prependOnceListener(event: "newSession", listener: (sessionId: any, sessionData: any, callback: (err: Error, resp: Buffer) => void) => void): this; + prependOnceListener(event: "OCSPRequest", listener: (certificate: Buffer, issuer: Buffer, callback: Function) => void): this; + prependOnceListener(event: "resumeSession", listener: (sessionId: any, callback: (err: Error, sessionData: any) => void) => void): this; + prependOnceListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this; + } - export interface ClearTextStream extends stream.Duplex { - authorized: boolean; - authorizationError: Error; - getPeerCertificate(): any; - getCipher: { - name: string; - version: string; - }; - address: { - port: number; - family: string; - address: string; - }; - remoteAddress: string; - remotePort: number; - } + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } - export interface SecurePair { - encrypted: any; - cleartext: any; - } + export interface SecurePair { + encrypted: any; + cleartext: any; + } - export interface SecureContextOptions { - pfx?: string | Buffer | Array; - key?: string | Buffer | Array; - passphrase?: string; - cert?: string | Buffer | Array; - ca?: string | Buffer | Array; - ciphers?: string; - honorCipherOrder?: boolean; - ecdhCurve?: string; - crl?: string | Buffer | Array; - dhparam?: string | Buffer; - secureOptions?: number; // Value is a numeric bitmask of the `SSL_OP_*` options - secureProtocol?: string; // SSL Method, e.g. SSLv23_method - sessionIdContext?: string; - } + export interface SecureContextOptions { + pfx?: string | Buffer; + key?: string | Buffer; + passphrase?: string; + cert?: string | Buffer; + ca?: string | Buffer; + crl?: string | string[] + ciphers?: string; + honorCipherOrder?: boolean; + } - export interface SecureContext { - context: any; - } + export interface SecureContext { + context: any; + } - /* - * Verifies the certificate `cert` is issued to host `host`. - * @host The hostname to verify the certificate against - * @cert PeerCertificate representing the peer's certificate - * - * Returns Error object, populating it with the reason, host and cert on failure. On success, returns undefined. - */ - export function checkServerIdentity(host: string, cert: PeerCertificate): Error | undefined; - export function createServer(options: TlsOptions, secureConnectionListener?: (socket: TLSSocket) => void): Server; - export function connect(options: ConnectionOptions, secureConnectionListener?: () => void): TLSSocket; - export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; - export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; - export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; - export function createSecureContext(details: SecureContextOptions): SecureContext; - export function getCiphers(): string[]; - - export var DEFAULT_ECDH_CURVE: string; + export function createServer(options: TlsOptions, secureConnectionListener?: (socket: TLSSocket) => void): Server; + export function connect(options: ConnectionOptions, secureConnectionListener?: () => void): TLSSocket; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; } declare module "crypto" { - export interface Certificate { - exportChallenge(spkac: string | Buffer): Buffer; - exportPublicKey(spkac: string | Buffer): Buffer; - verifySpkac(spkac: Buffer): boolean; - } - export var Certificate: { - new(): Certificate; - (): Certificate; - }; + export interface Certificate { + exportChallenge(spkac: string | Buffer): Buffer; + exportPublicKey(spkac: string | Buffer): Buffer; + verifySpkac(spkac: Buffer): boolean; + } + export var Certificate: { + new(): Certificate; + (): Certificate; + } - export var fips: boolean; + export var fips: boolean; - export interface CredentialDetails { - pfx: string; - key: string; - passphrase: string; - cert: string; - ca: string | string[]; - crl: string | string[]; - ciphers: string; - } - export interface Credentials { context?: any; } - export function createCredentials(details: CredentialDetails): Credentials; - export function createHash(algorithm: string): Hash; - export function createHmac(algorithm: string, key: string | Buffer): Hmac; + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: string | string[]; + crl: string | string[]; + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string | Buffer): Hmac; - type Utf8AsciiLatin1Encoding = "utf8" | "ascii" | "latin1"; - type HexBase64Latin1Encoding = "latin1" | "hex" | "base64"; - type Utf8AsciiBinaryEncoding = "utf8" | "ascii" | "binary"; - type HexBase64BinaryEncoding = "binary" | "base64" | "hex"; - type ECDHKeyFormat = "compressed" | "uncompressed" | "hybrid"; + type Utf8AsciiLatin1Encoding = "utf8" | "ascii" | "latin1"; + type HexBase64Latin1Encoding = "latin1" | "hex" | "base64"; + type Utf8AsciiBinaryEncoding = "utf8" | "ascii" | "binary"; + type HexBase64BinaryEncoding = "binary" | "base64" | "hex"; + type ECDHKeyFormat = "compressed" | "uncompressed" | "hybrid"; - export interface Hash extends NodeJS.ReadWriteStream { - update(data: string | Buffer | DataView): Hash; - update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Hash; - digest(): Buffer; - digest(encoding: HexBase64Latin1Encoding): string; - } - export interface Hmac extends NodeJS.ReadWriteStream { - update(data: string | Buffer | DataView): Hmac; - update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Hmac; - digest(): Buffer; - digest(encoding: HexBase64Latin1Encoding): string; - } - export function createCipher(algorithm: string, password: any): Cipher; - export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; - export interface Cipher extends NodeJS.ReadWriteStream { - update(data: Buffer | DataView): Buffer; - update(data: string, input_encoding: Utf8AsciiBinaryEncoding): Buffer; - update(data: Buffer | DataView, input_encoding: any, output_encoding: HexBase64BinaryEncoding): string; - update(data: string, input_encoding: Utf8AsciiBinaryEncoding, output_encoding: HexBase64BinaryEncoding): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding?: boolean): void; - getAuthTag(): Buffer; - setAAD(buffer: Buffer): void; - } - export function createDecipher(algorithm: string, password: any): Decipher; - export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; - export interface Decipher extends NodeJS.ReadWriteStream { - update(data: Buffer | DataView): Buffer; - update(data: string, input_encoding: HexBase64BinaryEncoding): Buffer; - update(data: Buffer | DataView, input_encoding: any, output_encoding: Utf8AsciiBinaryEncoding): string; - update(data: string, input_encoding: HexBase64BinaryEncoding, output_encoding: Utf8AsciiBinaryEncoding): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding?: boolean): void; - setAuthTag(tag: Buffer): void; - setAAD(buffer: Buffer): void; - } - export function createSign(algorithm: string): Signer; - export interface Signer extends NodeJS.WritableStream { - update(data: string | Buffer | DataView): Signer; - update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Signer; - sign(private_key: string | { key: string; passphrase: string }): Buffer; - sign(private_key: string | { key: string; passphrase: string }, output_format: HexBase64Latin1Encoding): string; - } - export function createVerify(algorith: string): Verify; - export interface Verify extends NodeJS.WritableStream { - update(data: string | Buffer | DataView): Verify; - update(data: string | Buffer | DataView, input_encoding: Utf8AsciiLatin1Encoding): Verify; - verify(object: string | Object, signature: Buffer | DataView): boolean; - verify(object: string | Object, signature: string, signature_format: HexBase64Latin1Encoding): boolean; - // https://nodejs.org/api/crypto.html#crypto_verifier_verify_object_signature_signature_format - // The signature field accepts a TypedArray type, but it is only available starting ES2017 - } - export function createDiffieHellman(prime_length: number, generator?: number): DiffieHellman; - export function createDiffieHellman(prime: Buffer): DiffieHellman; - export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding): DiffieHellman; - export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: number | Buffer): DiffieHellman; - export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: string, generator_encoding: HexBase64Latin1Encoding): DiffieHellman; - export interface DiffieHellman { - generateKeys(): Buffer; - generateKeys(encoding: HexBase64Latin1Encoding): string; - computeSecret(other_public_key: Buffer): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; - getPrime(): Buffer; - getPrime(encoding: HexBase64Latin1Encoding): string; - getGenerator(): Buffer; - getGenerator(encoding: HexBase64Latin1Encoding): string; - getPublicKey(): Buffer; - getPublicKey(encoding: HexBase64Latin1Encoding): string; - getPrivateKey(): Buffer; - getPrivateKey(encoding: HexBase64Latin1Encoding): string; - setPublicKey(public_key: Buffer): void; - setPublicKey(public_key: string, encoding: string): void; - setPrivateKey(private_key: Buffer): void; - setPrivateKey(private_key: string, encoding: string): void; - verifyError: number; - } - export function getDiffieHellman(group_name: string): DiffieHellman; - export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; - export function randomBytes(size: number): Buffer; - export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; - export function pseudoRandomBytes(size: number): Buffer; - export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; - export function randomFillSync(buffer: Buffer | Uint8Array, offset?: number, size?: number): Buffer; - export function randomFill(buffer: Buffer, callback: (err: Error, buf: Buffer) => void): void; - export function randomFill(buffer: Uint8Array, callback: (err: Error, buf: Uint8Array) => void): void; - export function randomFill(buffer: Buffer, offset: number, callback: (err: Error, buf: Buffer) => void): void; - export function randomFill(buffer: Uint8Array, offset: number, callback: (err: Error, buf: Uint8Array) => void): void; - export function randomFill(buffer: Buffer, offset: number, size: number, callback: (err: Error, buf: Buffer) => void): void; - export function randomFill(buffer: Uint8Array, offset: number, size: number, callback: (err: Error, buf: Uint8Array) => void): void; - export interface RsaPublicKey { - key: string; - padding?: number; - } - export interface RsaPrivateKey { - key: string; - passphrase?: string; - padding?: number; - } - export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer; - export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer; - export function privateEncrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer; - export function publicDecrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer; - export function getCiphers(): string[]; - export function getCurves(): string[]; - export function getHashes(): string[]; - export interface ECDH { - generateKeys(): Buffer; - generateKeys(encoding: HexBase64Latin1Encoding): string; - generateKeys(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; - computeSecret(other_public_key: Buffer): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; - computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; - getPrivateKey(): Buffer; - getPrivateKey(encoding: HexBase64Latin1Encoding): string; - getPublicKey(): Buffer; - getPublicKey(encoding: HexBase64Latin1Encoding): string; - getPublicKey(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; - setPrivateKey(private_key: Buffer): void; - setPrivateKey(private_key: string, encoding: HexBase64Latin1Encoding): void; - } - export function createECDH(curve_name: string): ECDH; - export function timingSafeEqual(a: Buffer, b: Buffer): boolean; - export var DEFAULT_ENCODING: string; + export interface Hash extends NodeJS.ReadWriteStream { + update(data: string | Buffer): Hash; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hash; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export interface Hmac extends NodeJS.ReadWriteStream { + update(data: string | Buffer): Hmac; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hmac; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + export interface Cipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: HexBase64BinaryEncoding): string; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding, output_encoding: HexBase64BinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): void; + getAuthTag(): Buffer; + setAAD(buffer: Buffer): void; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + export interface Decipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: HexBase64BinaryEncoding): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: Utf8AsciiBinaryEncoding): string; + update(data: string, input_encoding: HexBase64BinaryEncoding, output_encoding: Utf8AsciiBinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): void; + setAuthTag(tag: Buffer): void; + setAAD(buffer: Buffer): void; + } + export function createSign(algorithm: string): Signer; + export interface Signer extends NodeJS.WritableStream { + update(data: string | Buffer): Signer; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Signer; + sign(private_key: string | { key: string; passphrase: string }): Buffer; + sign(private_key: string | { key: string; passphrase: string }, output_format: HexBase64Latin1Encoding): string; + } + export function createVerify(algorith: string): Verify; + export interface Verify extends NodeJS.WritableStream { + update(data: string | Buffer): Verify; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Verify; + verify(object: string, signature: Buffer): boolean; + verify(object: string, signature: string, signature_format: HexBase64Latin1Encoding): boolean; + } + export function createDiffieHellman(prime_length: number, generator?: number): DiffieHellman; + export function createDiffieHellman(prime: Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: number | Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: string, generator_encoding: HexBase64Latin1Encoding): DiffieHellman; + export interface DiffieHellman { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrime(): Buffer; + getPrime(encoding: HexBase64Latin1Encoding): string; + getGenerator(): Buffer; + getGenerator(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + setPublicKey(public_key: Buffer): void; + setPublicKey(public_key: string, encoding: string): void; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: string): void; + verifyError: number; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export function randomFillSync(buffer: Buffer | Uint8Array, offset?: number, size?: number): Buffer; + export function randomFill(buffer: Buffer, callback: (err: Error, buf: Buffer) => void): void; + export function randomFill(buffer: Uint8Array, callback: (err: Error, buf: Uint8Array) => void): void; + export function randomFill(buffer: Buffer, offset: number, callback: (err: Error, buf: Buffer) => void): void; + export function randomFill(buffer: Uint8Array, offset: number, callback: (err: Error, buf: Uint8Array) => void): void; + export function randomFill(buffer: Buffer, offset: number, size: number, callback: (err: Error, buf: Buffer) => void): void; + export function randomFill(buffer: Uint8Array, offset: number, size: number, callback: (err: Error, buf: Uint8Array) => void): void; + export interface RsaPublicKey { + key: string; + padding?: number; + } + export interface RsaPrivateKey { + key: string; + passphrase?: string, + padding?: number; + } + export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer + export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer + export function privateEncrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer + export function publicDecrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer + export function getCiphers(): string[]; + export function getCurves(): string[]; + export function getHashes(): string[]; + export interface ECDH { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + generateKeys(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: HexBase64Latin1Encoding): void; + } + export function createECDH(curve_name: string): ECDH; + export function timingSafeEqual(a: Buffer, b: Buffer): boolean; + export var DEFAULT_ENCODING: string; } declare module "stream" { - import * as events from "events"; + import * as events from "events"; - class internal extends events.EventEmitter { - pipe(destination: T, options?: { end?: boolean; }): T; - } + class internal extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } - namespace internal { - export class Stream extends internal { } + namespace internal { - export interface ReadableOptions { - highWaterMark?: number; - encoding?: string; - objectMode?: boolean; - read?: (this: Readable, size?: number) => any; - destroy?: (error?: Error) => any; - } + export class Stream extends internal { } - export class Readable extends Stream implements NodeJS.ReadableStream { - readable: boolean; - constructor(opts?: ReadableOptions); - _read(size: number): void; - read(size?: number): any; - setEncoding(encoding: string): this; - pause(): this; - resume(): this; - isPaused(): boolean; - unpipe(destination?: T): this; - unshift(chunk: any): void; - wrap(oldStream: NodeJS.ReadableStream): this; - push(chunk: any, encoding?: string): boolean; - _destroy(err: Error, callback: Function): void; - destroy(error?: Error): void; + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + read?: (this: Readable, size?: number) => any; + } + + export class Readable extends Stream implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): this; + pause(): this; + resume(): this; + isPaused(): boolean; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): this; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): Readable; + push(chunk: any, encoding?: string): boolean; /** * Event emitter * The defined events on documents including: - * 1. close - * 2. data - * 3. end - * 4. readable - * 5. error - */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "data", listener: (chunk: Buffer | string) => void): this; - addListener(event: "end", listener: () => void): this; - addListener(event: "readable", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; + * 1. close + * 2. data + * 3. end + * 4. readable + * 5. error + **/ + addListener(event: string, listener: Function): this; + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "data", listener: (chunk: Buffer | string) => void): this; + addListener(event: "end", listener: () => void): this; + addListener(event: "readable", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "data", chunk: Buffer | string): boolean; - emit(event: "end"): boolean; - emit(event: "readable"): boolean; - emit(event: "error", err: Error): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "data", chunk: Buffer | string): boolean; + emit(event: "end"): boolean; + emit(event: "readable"): boolean; + emit(event: "error", err: Error): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: () => void): this; - on(event: "data", listener: (chunk: Buffer | string) => void): this; - on(event: "end", listener: () => void): this; - on(event: "readable", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "data", listener: (chunk: Buffer | string) => void): this; + on(event: "end", listener: () => void): this; + on(event: "readable", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: () => void): this; - once(event: "data", listener: (chunk: Buffer | string) => void): this; - once(event: "end", listener: () => void): this; - once(event: "readable", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "data", listener: (chunk: Buffer | string) => void): this; + once(event: "end", listener: () => void): this; + once(event: "readable", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; - prependListener(event: "end", listener: () => void): this; - prependListener(event: "readable", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependListener(event: "end", listener: () => void): this; + prependListener(event: "readable", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; - prependOnceListener(event: "end", listener: () => void): this; - prependOnceListener(event: "readable", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependOnceListener(event: "end", listener: () => void): this; + prependOnceListener(event: "readable", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; - removeListener(event: string, listener: (...args: any[]) => void): this; - removeListener(event: "close", listener: () => void): this; - removeListener(event: "data", listener: (chunk: Buffer | string) => void): this; - removeListener(event: "end", listener: () => void): this; - removeListener(event: "readable", listener: () => void): this; - removeListener(event: "error", listener: (err: Error) => void): this; - } + removeListener(event: string, listener: Function): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "data", listener: (chunk: Buffer | string) => void): this; + removeListener(event: "end", listener: () => void): this; + removeListener(event: "readable", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + } - export interface WritableOptions { - highWaterMark?: number; - decodeStrings?: boolean; - objectMode?: boolean; - write?: (chunk: string | Buffer, encoding: string, callback: Function) => any; - writev?: (chunks: Array<{ chunk: string | Buffer, encoding: string }>, callback: Function) => any; - destroy?: (error?: Error) => any; - final?: (callback: (error?: Error) => void) => void; - } + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + objectMode?: boolean; + write?: (chunk: string | Buffer, encoding: string, callback: Function) => any; + writev?: (chunks: { chunk: string | Buffer, encoding: string }[], callback: Function) => any; + } - export class Writable extends Stream implements NodeJS.WritableStream { - writable: boolean; - constructor(opts?: WritableOptions); - _write(chunk: any, encoding: string, callback: (err?: Error) => void): void; - _writev?(chunks: Array<{ chunk: any, encoding: string }>, callback: (err?: Error) => void): void; - _destroy(err: Error, callback: Function): void; - _final(callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - setDefaultEncoding(encoding: string): this; - end(cb?: Function): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - cork(): void; - uncork(): void; - destroy(error?: Error): void; + export class Writable extends Stream implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + setDefaultEncoding(encoding: string): this; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; /** * Event emitter * The defined events on documents including: - * 1. close - * 2. drain - * 3. error - * 4. finish - * 5. pipe - * 6. unpipe - */ - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "finish", listener: () => void): this; - addListener(event: "pipe", listener: (src: Readable) => void): this; - addListener(event: "unpipe", listener: (src: Readable) => void): this; + * 1. close + * 2. drain + * 3. error + * 4. finish + * 5. pipe + * 6. unpipe + **/ + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "finish", listener: () => void): this; + addListener(event: "pipe", listener: (src: Readable) => void): this; + addListener(event: "unpipe", listener: (src: Readable) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "drain", chunk: Buffer | string): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "finish"): boolean; - emit(event: "pipe", src: Readable): boolean; - emit(event: "unpipe", src: Readable): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "drain", chunk: Buffer | string): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "finish"): boolean; + emit(event: "pipe", src: Readable): boolean; + emit(event: "unpipe", src: Readable): boolean; - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: () => void): this; - on(event: "drain", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "finish", listener: () => void): this; - on(event: "pipe", listener: (src: Readable) => void): this; - on(event: "unpipe", listener: (src: Readable) => void): this; + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "drain", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "finish", listener: () => void): this; + on(event: "pipe", listener: (src: Readable) => void): this; + on(event: "unpipe", listener: (src: Readable) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: () => void): this; - once(event: "drain", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "finish", listener: () => void): this; - once(event: "pipe", listener: (src: Readable) => void): this; - once(event: "unpipe", listener: (src: Readable) => void): this; + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "drain", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "finish", listener: () => void): this; + once(event: "pipe", listener: (src: Readable) => void): this; + once(event: "unpipe", listener: (src: Readable) => void): this; - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "finish", listener: () => void): this; - prependListener(event: "pipe", listener: (src: Readable) => void): this; - prependListener(event: "unpipe", listener: (src: Readable) => void): this; + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "finish", listener: () => void): this; + prependListener(event: "pipe", listener: (src: Readable) => void): this; + prependListener(event: "unpipe", listener: (src: Readable) => void): this; - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "finish", listener: () => void): this; - prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; - prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "finish", listener: () => void): this; + prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; + prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; - removeListener(event: string, listener: (...args: any[]) => void): this; - removeListener(event: "close", listener: () => void): this; - removeListener(event: "drain", listener: () => void): this; - removeListener(event: "error", listener: (err: Error) => void): this; - removeListener(event: "finish", listener: () => void): this; - removeListener(event: "pipe", listener: (src: Readable) => void): this; - removeListener(event: "unpipe", listener: (src: Readable) => void): this; - } + removeListener(event: string, listener: Function): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "drain", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + removeListener(event: "finish", listener: () => void): this; + removeListener(event: "pipe", listener: (src: Readable) => void): this; + removeListener(event: "unpipe", listener: (src: Readable) => void): this; + } - export interface DuplexOptions extends ReadableOptions, WritableOptions { - allowHalfOpen?: boolean; - readableObjectMode?: boolean; - writableObjectMode?: boolean; - } + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + readableObjectMode?: boolean; + writableObjectMode?: boolean; + } - // Note: Duplex extends both Readable and Writable. - export class Duplex extends Readable implements Writable { - writable: boolean; - constructor(opts?: DuplexOptions); - _write(chunk: any, encoding: string, callback: (err?: Error) => void): void; - _writev?(chunks: Array<{ chunk: any, encoding: string }>, callback: (err?: Error) => void): void; - _destroy(err: Error, callback: Function): void; - _final(callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - setDefaultEncoding(encoding: string): this; - end(cb?: Function): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - cork(): void; - uncork(): void; - } + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements Writable { + writable: boolean; + constructor(opts?: DuplexOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + setDefaultEncoding(encoding: string): this; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } - export interface TransformOptions extends DuplexOptions { - transform?: (chunk: string | Buffer, encoding: string, callback: Function) => any; - flush?: (callback: Function) => any; - } + export interface TransformOptions extends DuplexOptions { + transform?: (chunk: string | Buffer, encoding: string, callback: Function) => any; + flush?: (callback: Function) => any; + } - export class Transform extends Duplex { - constructor(opts?: TransformOptions); - _transform(chunk: any, encoding: string, callback: Function): void; - destroy(error?: Error): void; - } + export class Transform extends Duplex { + constructor(opts?: TransformOptions); + _transform(chunk: any, encoding: string, callback: Function): void; + } - export class PassThrough extends Transform { } - } + export class PassThrough extends Transform { } + } - export = internal; + export = internal; } declare module "util" { - export interface InspectOptions extends NodeJS.InspectOptions { } - export function format(format: any, ...param: any[]): string; - export function debug(string: string): void; - export function error(...param: any[]): void; - export function puts(...param: any[]): void; - export function print(...param: any[]): void; - export function log(string: string): void; - export var inspect: { - (object: any, showHidden?: boolean, depth?: number | null, color?: boolean): string; - (object: any, options: InspectOptions): string; - colors: { - [color: string]: [number, number] | undefined - } - styles: { - [style: string]: string | undefined - } - defaultOptions: InspectOptions; - custom: symbol; - }; - export function isArray(object: any): object is any[]; - export function isRegExp(object: any): object is RegExp; - export function isDate(object: any): object is Date; - export function isError(object: any): object is Error; - export function inherits(constructor: any, superConstructor: any): void; - export function debuglog(key: string): (msg: string, ...param: any[]) => void; - export function isBoolean(object: any): object is boolean; - export function isBuffer(object: any): object is Buffer; - export function isFunction(object: any): boolean; - export function isNull(object: any): object is null; - export function isNullOrUndefined(object: any): object is null | undefined; - export function isNumber(object: any): object is number; - export function isObject(object: any): boolean; - export function isPrimitive(object: any): boolean; - export function isString(object: any): object is string; - export function isSymbol(object: any): object is symbol; - export function isUndefined(object: any): object is undefined; - export function deprecate(fn: T, message: string): T; - - export interface CustomPromisify extends Function { - __promisify__: TCustom; - } - - export function callbackify(fn: () => Promise): (callback: (err: NodeJS.ErrnoException) => void) => void; - export function callbackify(fn: () => Promise): (callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; - export function callbackify(fn: (arg1: T1) => Promise): (arg1: T1, callback: (err: NodeJS.ErrnoException) => void) => void; - export function callbackify(fn: (arg1: T1) => Promise): (arg1: T1, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2) => Promise): (arg1: T1, arg2: T2, callback: (err: NodeJS.ErrnoException) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2) => Promise): (arg1: T1, arg2: T2, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3) => Promise): (arg1: T1, arg2: T2, arg3: T3, callback: (err: NodeJS.ErrnoException) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3) => Promise): (arg1: T1, arg2: T2, arg3: T3, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: NodeJS.ErrnoException) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: NodeJS.ErrnoException) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, callback: (err: NodeJS.ErrnoException) => void) => void; - export function callbackify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => Promise): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, callback: (err: NodeJS.ErrnoException, result: TResult) => void) => void; - - export function promisify(fn: CustomPromisify): TCustom; - export function promisify(fn: (callback: (err: Error, result: TResult) => void) => void): () => Promise; - export function promisify(fn: (callback: (err: Error) => void) => void): () => Promise; - export function promisify(fn: (arg1: T1, callback: (err: Error, result: TResult) => void) => void): (arg1: T1) => Promise; - export function promisify(fn: (arg1: T1, callback: (err: Error) => void) => void): (arg1: T1) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, callback: (err: Error, result: TResult) => void) => void): (arg1: T1, arg2: T2) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, callback: (err: Error) => void) => void): (arg1: T1, arg2: T2) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, callback: (err: Error, result: TResult) => void) => void): (arg1: T1, arg2: T2, arg3: T3) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, callback: (err: Error) => void) => void): (arg1: T1, arg2: T2, arg3: T3) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: Error, result: TResult) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, callback: (err: Error) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: Error, result: TResult) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise; - export function promisify(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, callback: (err: Error) => void) => void): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise; - export function promisify(fn: Function): Function; - export namespace promisify { - const custom: symbol; - } + export interface InspectOptions extends NodeJS.InspectOptions { } + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number | null, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): object is any[]; + export function isRegExp(object: any): object is RegExp; + export function isDate(object: any): object is Date; + export function isError(object: any): object is Error; + export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key: string): (msg: string, ...param: any[]) => void; + export function isBoolean(object: any): object is boolean; + export function isBuffer(object: any): object is Buffer; + export function isFunction(object: any): boolean; + export function isNull(object: any): object is null; + export function isNullOrUndefined(object: any): object is null | undefined; + export function isNumber(object: any): object is number; + export function isObject(object: any): boolean; + export function isPrimitive(object: any): boolean; + export function isString(object: any): object is string; + export function isSymbol(object: any): object is symbol; + export function isUndefined(object: any): object is undefined; + export function deprecate(fn: T, message: string): T; } declare module "assert" { - function internal(value: any, message?: string): void; - namespace internal { - export class AssertionError implements Error { - name: string; - message: string; - actual: any; - expected: any; - operator: string; - generatedMessage: boolean; + function internal(value: any, message?: string): void; + namespace internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; - constructor(options?: { - message?: string; actual?: any; expected?: any; - operator?: string; stackStartFunction?: Function - }); - } + constructor(options?: { + message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function + }); + } - export function fail(message: string): void; - export function fail(actual: any, expected: any, message?: string, operator?: string): void; - export function ok(value: any, message?: string): void; - export function equal(actual: any, expected: any, message?: string): void; - export function notEqual(actual: any, expected: any, message?: string): void; - export function deepEqual(actual: any, expected: any, message?: string): void; - export function notDeepEqual(acutal: any, expected: any, message?: string): void; - export function strictEqual(actual: any, expected: any, message?: string): void; - export function notStrictEqual(actual: any, expected: any, message?: string): void; - export function deepStrictEqual(actual: any, expected: any, message?: string): void; - export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; + export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export function deepStrictEqual(actual: any, expected: any, message?: string): void; + export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; - export function throws(block: Function, message?: string): void; - export function throws(block: Function, error: Function, message?: string): void; - export function throws(block: Function, error: RegExp, message?: string): void; - export function throws(block: Function, error: (err: any) => boolean, message?: string): void; + export function throws(block: Function, message?: string): void; + export function throws(block: Function, error: Function, message?: string): void; + export function throws(block: Function, error: RegExp, message?: string): void; + export function throws(block: Function, error: (err: any) => boolean, message?: string): void; - export function doesNotThrow(block: Function, message?: string): void; - export function doesNotThrow(block: Function, error: Function, message?: string): void; - export function doesNotThrow(block: Function, error: RegExp, message?: string): void; - export function doesNotThrow(block: Function, error: (err: any) => boolean, message?: string): void; + export function doesNotThrow(block: Function, message?: string): void; + export function doesNotThrow(block: Function, error: Function, message?: string): void; + export function doesNotThrow(block: Function, error: RegExp, message?: string): void; + export function doesNotThrow(block: Function, error: (err: any) => boolean, message?: string): void; - export function ifError(value: any): void; - } + export function ifError(value: any): void; + } - export = internal; + export = internal; } declare module "tty" { - import * as net from "net"; + import * as net from "net"; - export function isatty(fd: number): boolean; - export class ReadStream extends net.Socket { - isRaw: boolean; - setRawMode(mode: boolean): void; - isTTY: boolean; - } - export class WriteStream extends net.Socket { - columns: number; - rows: number; - isTTY: boolean; - } + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + isTTY: boolean; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + isTTY: boolean; + } } declare module "domain" { - import * as events from "events"; + import * as events from "events"; - export class Domain extends events.EventEmitter implements NodeJS.Domain { - run(fn: Function): void; - add(emitter: events.EventEmitter): void; - remove(emitter: events.EventEmitter): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - members: any[]; - enter(): void; - exit(): void; - } + export class Domain extends events.EventEmitter implements NodeJS.Domain { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + members: any[]; + enter(): void; + exit(): void; + } - export function create(): Domain; + export function create(): Domain; } declare module "constants" { - export var E2BIG: number; - export var EACCES: number; - export var EADDRINUSE: number; - export var EADDRNOTAVAIL: number; - export var EAFNOSUPPORT: number; - export var EAGAIN: number; - export var EALREADY: number; - export var EBADF: number; - export var EBADMSG: number; - export var EBUSY: number; - export var ECANCELED: number; - export var ECHILD: number; - export var ECONNABORTED: number; - export var ECONNREFUSED: number; - export var ECONNRESET: number; - export var EDEADLK: number; - export var EDESTADDRREQ: number; - export var EDOM: number; - export var EEXIST: number; - export var EFAULT: number; - export var EFBIG: number; - export var EHOSTUNREACH: number; - export var EIDRM: number; - export var EILSEQ: number; - export var EINPROGRESS: number; - export var EINTR: number; - export var EINVAL: number; - export var EIO: number; - export var EISCONN: number; - export var EISDIR: number; - export var ELOOP: number; - export var EMFILE: number; - export var EMLINK: number; - export var EMSGSIZE: number; - export var ENAMETOOLONG: number; - export var ENETDOWN: number; - export var ENETRESET: number; - export var ENETUNREACH: number; - export var ENFILE: number; - export var ENOBUFS: number; - export var ENODATA: number; - export var ENODEV: number; - export var ENOENT: number; - export var ENOEXEC: number; - export var ENOLCK: number; - export var ENOLINK: number; - export var ENOMEM: number; - export var ENOMSG: number; - export var ENOPROTOOPT: number; - export var ENOSPC: number; - export var ENOSR: number; - export var ENOSTR: number; - export var ENOSYS: number; - export var ENOTCONN: number; - export var ENOTDIR: number; - export var ENOTEMPTY: number; - export var ENOTSOCK: number; - export var ENOTSUP: number; - export var ENOTTY: number; - export var ENXIO: number; - export var EOPNOTSUPP: number; - export var EOVERFLOW: number; - export var EPERM: number; - export var EPIPE: number; - export var EPROTO: number; - export var EPROTONOSUPPORT: number; - export var EPROTOTYPE: number; - export var ERANGE: number; - export var EROFS: number; - export var ESPIPE: number; - export var ESRCH: number; - export var ETIME: number; - export var ETIMEDOUT: number; - export var ETXTBSY: number; - export var EWOULDBLOCK: number; - export var EXDEV: number; - export var WSAEINTR: number; - export var WSAEBADF: number; - export var WSAEACCES: number; - export var WSAEFAULT: number; - export var WSAEINVAL: number; - export var WSAEMFILE: number; - export var WSAEWOULDBLOCK: number; - export var WSAEINPROGRESS: number; - export var WSAEALREADY: number; - export var WSAENOTSOCK: number; - export var WSAEDESTADDRREQ: number; - export var WSAEMSGSIZE: number; - export var WSAEPROTOTYPE: number; - export var WSAENOPROTOOPT: number; - export var WSAEPROTONOSUPPORT: number; - export var WSAESOCKTNOSUPPORT: number; - export var WSAEOPNOTSUPP: number; - export var WSAEPFNOSUPPORT: number; - export var WSAEAFNOSUPPORT: number; - export var WSAEADDRINUSE: number; - export var WSAEADDRNOTAVAIL: number; - export var WSAENETDOWN: number; - export var WSAENETUNREACH: number; - export var WSAENETRESET: number; - export var WSAECONNABORTED: number; - export var WSAECONNRESET: number; - export var WSAENOBUFS: number; - export var WSAEISCONN: number; - export var WSAENOTCONN: number; - export var WSAESHUTDOWN: number; - export var WSAETOOMANYREFS: number; - export var WSAETIMEDOUT: number; - export var WSAECONNREFUSED: number; - export var WSAELOOP: number; - export var WSAENAMETOOLONG: number; - export var WSAEHOSTDOWN: number; - export var WSAEHOSTUNREACH: number; - export var WSAENOTEMPTY: number; - export var WSAEPROCLIM: number; - export var WSAEUSERS: number; - export var WSAEDQUOT: number; - export var WSAESTALE: number; - export var WSAEREMOTE: number; - export var WSASYSNOTREADY: number; - export var WSAVERNOTSUPPORTED: number; - export var WSANOTINITIALISED: number; - export var WSAEDISCON: number; - export var WSAENOMORE: number; - export var WSAECANCELLED: number; - export var WSAEINVALIDPROCTABLE: number; - export var WSAEINVALIDPROVIDER: number; - export var WSAEPROVIDERFAILEDINIT: number; - export var WSASYSCALLFAILURE: number; - export var WSASERVICE_NOT_FOUND: number; - export var WSATYPE_NOT_FOUND: number; - export var WSA_E_NO_MORE: number; - export var WSA_E_CANCELLED: number; - export var WSAEREFUSED: number; - export var SIGHUP: number; - export var SIGINT: number; - export var SIGILL: number; - export var SIGABRT: number; - export var SIGFPE: number; - export var SIGKILL: number; - export var SIGSEGV: number; - export var SIGTERM: number; - export var SIGBREAK: number; - export var SIGWINCH: number; - export var SSL_OP_ALL: number; - export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; - export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; - export var SSL_OP_CISCO_ANYCONNECT: number; - export var SSL_OP_COOKIE_EXCHANGE: number; - export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; - export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; - export var SSL_OP_EPHEMERAL_RSA: number; - export var SSL_OP_LEGACY_SERVER_CONNECT: number; - export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; - export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; - export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; - export var SSL_OP_NETSCAPE_CA_DN_BUG: number; - export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; - export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NO_COMPRESSION: number; - export var SSL_OP_NO_QUERY_MTU: number; - export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; - export var SSL_OP_NO_SSLv2: number; - export var SSL_OP_NO_SSLv3: number; - export var SSL_OP_NO_TICKET: number; - export var SSL_OP_NO_TLSv1: number; - export var SSL_OP_NO_TLSv1_1: number; - export var SSL_OP_NO_TLSv1_2: number; - export var SSL_OP_PKCS1_CHECK_1: number; - export var SSL_OP_PKCS1_CHECK_2: number; - export var SSL_OP_SINGLE_DH_USE: number; - export var SSL_OP_SINGLE_ECDH_USE: number; - export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; - export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; - export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; - export var SSL_OP_TLS_D5_BUG: number; - export var SSL_OP_TLS_ROLLBACK_BUG: number; - export var ENGINE_METHOD_DSA: number; - export var ENGINE_METHOD_DH: number; - export var ENGINE_METHOD_RAND: number; - export var ENGINE_METHOD_ECDH: number; - export var ENGINE_METHOD_ECDSA: number; - export var ENGINE_METHOD_CIPHERS: number; - export var ENGINE_METHOD_DIGESTS: number; - export var ENGINE_METHOD_STORE: number; - export var ENGINE_METHOD_PKEY_METHS: number; - export var ENGINE_METHOD_PKEY_ASN1_METHS: number; - export var ENGINE_METHOD_ALL: number; - export var ENGINE_METHOD_NONE: number; - export var DH_CHECK_P_NOT_SAFE_PRIME: number; - export var DH_CHECK_P_NOT_PRIME: number; - export var DH_UNABLE_TO_CHECK_GENERATOR: number; - export var DH_NOT_SUITABLE_GENERATOR: number; - export var NPN_ENABLED: number; - export var RSA_PKCS1_PADDING: number; - export var RSA_SSLV23_PADDING: number; - export var RSA_NO_PADDING: number; - export var RSA_PKCS1_OAEP_PADDING: number; - export var RSA_X931_PADDING: number; - export var RSA_PKCS1_PSS_PADDING: number; - export var POINT_CONVERSION_COMPRESSED: number; - export var POINT_CONVERSION_UNCOMPRESSED: number; - export var POINT_CONVERSION_HYBRID: number; - export var O_RDONLY: number; - export var O_WRONLY: number; - export var O_RDWR: number; - export var S_IFMT: number; - export var S_IFREG: number; - export var S_IFDIR: number; - export var S_IFCHR: number; - export var S_IFBLK: number; - export var S_IFIFO: number; - export var S_IFSOCK: number; - export var S_IRWXU: number; - export var S_IRUSR: number; - export var S_IWUSR: number; - export var S_IXUSR: number; - export var S_IRWXG: number; - export var S_IRGRP: number; - export var S_IWGRP: number; - export var S_IXGRP: number; - export var S_IRWXO: number; - export var S_IROTH: number; - export var S_IWOTH: number; - export var S_IXOTH: number; - export var S_IFLNK: number; - export var O_CREAT: number; - export var O_EXCL: number; - export var O_NOCTTY: number; - export var O_DIRECTORY: number; - export var O_NOATIME: number; - export var O_NOFOLLOW: number; - export var O_SYNC: number; - export var O_DSYNC: number; - export var O_SYMLINK: number; - export var O_DIRECT: number; - export var O_NONBLOCK: number; - export var O_TRUNC: number; - export var O_APPEND: number; - export var F_OK: number; - export var R_OK: number; - export var W_OK: number; - export var X_OK: number; - export var UV_UDP_REUSEADDR: number; - export var SIGQUIT: number; - export var SIGTRAP: number; - export var SIGIOT: number; - export var SIGBUS: number; - export var SIGUSR1: number; - export var SIGUSR2: number; - export var SIGPIPE: number; - export var SIGALRM: number; - export var SIGCHLD: number; - export var SIGSTKFLT: number; - export var SIGCONT: number; - export var SIGSTOP: number; - export var SIGTSTP: number; - export var SIGTTIN: number; - export var SIGTTOU: number; - export var SIGURG: number; - export var SIGXCPU: number; - export var SIGXFSZ: number; - export var SIGVTALRM: number; - export var SIGPROF: number; - export var SIGIO: number; - export var SIGPOLL: number; - export var SIGPWR: number; - export var SIGSYS: number; - export var SIGUNUSED: number; - export var defaultCoreCipherList: string; - export var defaultCipherList: string; - export var ENGINE_METHOD_RSA: number; - export var ALPN_ENABLED: number; -} - -declare module "module" { - export = NodeJS.Module; + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFBLK: number; + export var S_IFIFO: number; + export var S_IFSOCK: number; + export var S_IRWXU: number; + export var S_IRUSR: number; + export var S_IWUSR: number; + export var S_IXUSR: number; + export var S_IRWXG: number; + export var S_IRGRP: number; + export var S_IWGRP: number; + export var S_IXGRP: number; + export var S_IRWXO: number; + export var S_IROTH: number; + export var S_IWOTH: number; + export var S_IXOTH: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_NOCTTY: number; + export var O_DIRECTORY: number; + export var O_NOATIME: number; + export var O_NOFOLLOW: number; + export var O_SYNC: number; + export var O_SYMLINK: number; + export var O_DIRECT: number; + export var O_NONBLOCK: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; + export var SIGQUIT: number; + export var SIGTRAP: number; + export var SIGIOT: number; + export var SIGBUS: number; + export var SIGUSR1: number; + export var SIGUSR2: number; + export var SIGPIPE: number; + export var SIGALRM: number; + export var SIGCHLD: number; + export var SIGSTKFLT: number; + export var SIGCONT: number; + export var SIGSTOP: number; + export var SIGTSTP: number; + export var SIGTTIN: number; + export var SIGTTOU: number; + export var SIGURG: number; + export var SIGXCPU: number; + export var SIGXFSZ: number; + export var SIGVTALRM: number; + export var SIGPROF: number; + export var SIGIO: number; + export var SIGPOLL: number; + export var SIGPWR: number; + export var SIGSYS: number; + export var SIGUNUSED: number; + export var defaultCoreCipherList: string; + export var defaultCipherList: string; + export var ENGINE_METHOD_RSA: number; + export var ALPN_ENABLED: number; } declare module "process" { - export = process; + export = process; } -// tslint:disable-next-line:no-declare-current-package declare module "v8" { - interface HeapSpaceInfo { - space_name: string; - space_size: number; - space_used_size: number; - space_available_size: number; - physical_space_size: number; - } + interface HeapSpaceInfo { + space_name: string; + space_size: number; + space_used_size: number; + space_available_size: number; + physical_space_size: number; + } - // ** Signifies if the --zap_code_space option is enabled or not. 1 == enabled, 0 == disabled. */ - type DoesZapCodeSpaceFlag = 0 | 1; + //** Signifies if the --zap_code_space option is enabled or not. 1 == enabled, 0 == disabled. */ + type DoesZapCodeSpaceFlag = 0 | 1; - interface HeapInfo { - total_heap_size: number; - total_heap_size_executable: number; - total_physical_size: number; - total_available_size: number; - used_heap_size: number; - heap_size_limit: number; - malloced_memory: number; - peak_malloced_memory: number; - does_zap_garbage: DoesZapCodeSpaceFlag; - } + interface HeapInfo { + total_heap_size: number; + total_heap_size_executable: number; + total_physical_size: number; + total_available_size: number; + used_heap_size: number; + heap_size_limit: number; + malloced_memory: number; + peak_malloced_memory: number; + does_zap_garbage: DoesZapCodeSpaceFlag; + } - export function getHeapStatistics(): HeapInfo; - export function getHeapSpaceStatistics(): HeapSpaceInfo[]; - export function setFlagsFromString(flags: string): void; + export function getHeapStatistics(): HeapInfo; + export function getHeapSpaceStatistics(): HeapSpaceInfo[]; + export function setFlagsFromString(flags: string): void; } declare module "timers" { - export function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; - export namespace setTimeout { - export function __promisify__(ms: number): Promise; - export function __promisify__(ms: number, value: T): Promise; - } - export function clearTimeout(timeoutId: NodeJS.Timer): void; - export function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; - export function clearInterval(intervalId: NodeJS.Timer): void; - export function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; - export namespace setImmediate { - export function __promisify__(): Promise; - export function __promisify__(value: T): Promise; - } - export function clearImmediate(immediateId: any): void; + export function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export function clearTimeout(timeoutId: NodeJS.Timer): void; + export function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export function clearInterval(intervalId: NodeJS.Timer): void; + export function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; + export function clearImmediate(immediateId: any): void; } declare module "console" { - export = console; + export = console; } /** - * Async Hooks module: https://nodejs.org/api/async_hooks.html + * _debugger module is not documented. + * Source code is at https://github.com/nodejs/node/blob/master/lib/_debugger.js */ -declare module "async_hooks" { - /** - * Returns the asyncId of the current execution context. - */ - export function executionAsyncId(): number; - /// @deprecated - replaced by executionAsyncId() - export function currentId(): number; +declare module "_debugger" { + export interface Packet { + raw: string; + headers: string[]; + body: Message; + } - /** - * Returns the ID of the resource responsible for calling the callback that is currently being executed. - */ - export function triggerAsyncId(): number; - /// @deprecated - replaced by triggerAsyncId() - export function triggerId(): number; + export interface Message { + seq: number; + type: string; + } - export interface HookCallbacks { - /** - * Called when a class is constructed that has the possibility to emit an asynchronous event. - * @param asyncId a unique ID for the async resource - * @param type the type of the async resource - * @param triggerAsyncId the unique ID of the async resource in whose execution context this async resource was created - * @param resource reference to the resource representing the async operation, needs to be released during destroy - */ - init?(asyncId: number, type: string, triggerAsyncId: number, resource: Object): void; + export interface RequestInfo { + command: string; + arguments: any; + } - /** - * When an asynchronous operation is initiated or completes a callback is called to notify the user. - * The before callback is called just before said callback is executed. - * @param asyncId the unique identifier assigned to the resource about to execute the callback. - */ - before?(asyncId: number): void; + export interface Request extends Message, RequestInfo { + } - /** - * Called immediately after the callback specified in before is completed. - * @param asyncId the unique identifier assigned to the resource which has executed the callback. - */ - after?(asyncId: number): void; + export interface Event extends Message { + event: string; + body?: any; + } - /** - * Called when a promise has resolve() called. This may not be in the same execution id - * as the promise itself. - * @param asyncId the unique id for the promise that was resolve()d. - */ - promiseResolve?(asyncId: number): void; + export interface Response extends Message { + request_seq: number; + success: boolean; + /** Contains error message if success === false. */ + message?: string; + /** Contains message body if success === true. */ + body?: any; + } - /** - * Called after the resource corresponding to asyncId is destroyed - * @param asyncId a unique ID for the async resource - */ - destroy?(asyncId: number): void; - } + export interface BreakpointMessageBody { + type: string; + target: number; + line: number; + } - export interface AsyncHook { - /** - * Enable the callbacks for a given AsyncHook instance. If no callbacks are provided enabling is a noop. - */ - enable(): this; + export class Protocol { + res: Packet; + state: string; + execute(data: string): void; + serialize(rq: Request): string; + onResponse: (pkt: Packet) => void; + } - /** - * Disable the callbacks for a given AsyncHook instance from the global pool of AsyncHook callbacks to be executed. Once a hook has been disabled it will not be called again until enabled. - */ - disable(): this; - } + export var NO_FRAME: number; + export var port: number; - /** - * Registers functions to be called for different lifetime events of each async operation. - * @param options the callbacks to register - * @return an AsyncHooks instance used for disabling and enabling hooks - */ - export function createHook(options: HookCallbacks): AsyncHook; + export interface ScriptDesc { + name: string; + id: number; + isNative?: boolean; + handle?: number; + type: string; + lineOffset?: number; + columnOffset?: number; + lineCount?: number; + } - /** - * The class AsyncResource was designed to be extended by the embedder's async resources. - * Using this users can easily trigger the lifetime events of their own resources. - */ - export class AsyncResource { - /** - * AsyncResource() is meant to be extended. Instantiating a - * new AsyncResource() also triggers init. If triggerAsyncId is omitted then - * async_hook.executionAsyncId() is used. - * @param type the name of this async resource type - * @param triggerAsyncId the unique ID of the async resource in whose execution context this async resource was created - */ - constructor(type: string, triggerAsyncId?: number) + export interface Breakpoint { + id: number; + scriptId: number; + script: ScriptDesc; + line: number; + condition?: string; + scriptReq?: string; + } - /** - * Call AsyncHooks before callbacks. - */ - emitBefore(): void; + export interface RequestHandler { + (err: boolean, body: Message, res: Packet): void; + request_seq?: number; + } - /** - * Call AsyncHooks after callbacks - */ - emitAfter(): void; + export interface ResponseBodyHandler { + (err: boolean, body?: any): void; + request_seq?: number; + } - /** - * Call AsyncHooks destroy callbacks. - */ - emitDestroy(): void; + export interface ExceptionInfo { + text: string; + } - /** - * @return the unique ID assigned to this AsyncResource instance. - */ - asyncId(): number; + export interface BreakResponse { + script?: ScriptDesc; + exception?: ExceptionInfo; + sourceLine: number; + sourceLineText: string; + sourceColumn: number; + } - /** - * @return the trigger ID for this AsyncResource instance. - */ - triggerAsyncId(): number; - } + export function SourceInfo(body: BreakResponse): string; + + export interface ClientInstance extends NodeJS.EventEmitter { + protocol: Protocol; + scripts: ScriptDesc[]; + handles: ScriptDesc[]; + breakpoints: Breakpoint[]; + currentSourceLine: number; + currentSourceColumn: number; + currentSourceLineText: string; + currentFrame: number; + currentScript: string; + + connect(port: number, host: string): void; + req(req: any, cb: RequestHandler): void; + reqFrameEval(code: string, frame: number, cb: RequestHandler): void; + mirrorObject(obj: any, depth: number, cb: ResponseBodyHandler): void; + setBreakpoint(rq: BreakpointMessageBody, cb: RequestHandler): void; + clearBreakpoint(rq: Request, cb: RequestHandler): void; + listbreakpoints(cb: RequestHandler): void; + reqSource(from: number, to: number, cb: RequestHandler): void; + reqScripts(cb: any): void; + reqContinue(cb: RequestHandler): void; + } + + export var Client: { + new(): ClientInstance + } } - -declare module "http2" { - import * as events from "events"; - import * as fs from "fs"; - import * as net from "net"; - import * as stream from "stream"; - import * as tls from "tls"; - import * as url from "url"; - - import { IncomingHttpHeaders, OutgoingHttpHeaders } from "http"; - export { IncomingHttpHeaders, OutgoingHttpHeaders } from "http"; - - // Http2Stream - - export interface StreamPriorityOptions { - exclusive?: boolean; - parent?: number; - weight?: number; - silent?: boolean; - } - - export interface StreamState { - localWindowSize?: number; - state?: number; - streamLocalClose?: number; - streamRemoteClose?: number; - sumDependencyWeight?: number; - weight?: number; - } - - export interface ServerStreamResponseOptions { - endStream?: boolean; - getTrailers?: (trailers: OutgoingHttpHeaders) => void; - } - - export interface StatOptions { - offset: number; - length: number; - } - - export interface ServerStreamFileResponseOptions { - statCheck?: (stats: fs.Stats, headers: OutgoingHttpHeaders, statOptions: StatOptions) => void | boolean; - getTrailers?: (trailers: OutgoingHttpHeaders) => void; - offset?: number; - length?: number; - } - - export interface ServerStreamFileResponseOptionsWithError extends ServerStreamFileResponseOptions { - onError?: (err: NodeJS.ErrnoException) => void; - } - - export interface Http2Stream extends stream.Duplex { - readonly aborted: boolean; - readonly destroyed: boolean; - priority(options: StreamPriorityOptions): void; - readonly rstCode: number; - rstStream(code: number): void; - rstWithNoError(): void; - rstWithProtocolError(): void; - rstWithCancel(): void; - rstWithRefuse(): void; - rstWithInternalError(): void; - readonly session: Http2Session; - setTimeout(msecs: number, callback?: () => void): void; - readonly state: StreamState; - - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "aborted", listener: () => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "data", listener: (chunk: Buffer | string) => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "end", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "finish", listener: () => void): this; - addListener(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; - addListener(event: "pipe", listener: (src: stream.Readable) => void): this; - addListener(event: "unpipe", listener: (src: stream.Readable) => void): this; - addListener(event: "streamClosed", listener: (code: number) => void): this; - addListener(event: "timeout", listener: () => void): this; - addListener(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "aborted"): boolean; - emit(event: "close"): boolean; - emit(event: "data", chunk: Buffer | string): boolean; - emit(event: "drain"): boolean; - emit(event: "end"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "finish"): boolean; - emit(event: "frameError", frameType: number, errorCode: number): boolean; - emit(event: "pipe", src: stream.Readable): boolean; - emit(event: "unpipe", src: stream.Readable): boolean; - emit(event: "streamClosed", code: number): boolean; - emit(event: "timeout"): boolean; - emit(event: "trailers", trailers: IncomingHttpHeaders, flags: number): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "aborted", listener: () => void): this; - on(event: "close", listener: () => void): this; - on(event: "data", listener: (chunk: Buffer | string) => void): this; - on(event: "drain", listener: () => void): this; - on(event: "end", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "finish", listener: () => void): this; - on(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; - on(event: "pipe", listener: (src: stream.Readable) => void): this; - on(event: "unpipe", listener: (src: stream.Readable) => void): this; - on(event: "streamClosed", listener: (code: number) => void): this; - on(event: "timeout", listener: () => void): this; - on(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "aborted", listener: () => void): this; - once(event: "close", listener: () => void): this; - once(event: "data", listener: (chunk: Buffer | string) => void): this; - once(event: "drain", listener: () => void): this; - once(event: "end", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "finish", listener: () => void): this; - once(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; - once(event: "pipe", listener: (src: stream.Readable) => void): this; - once(event: "unpipe", listener: (src: stream.Readable) => void): this; - once(event: "streamClosed", listener: (code: number) => void): this; - once(event: "timeout", listener: () => void): this; - once(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "aborted", listener: () => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "end", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "finish", listener: () => void): this; - prependListener(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; - prependListener(event: "pipe", listener: (src: stream.Readable) => void): this; - prependListener(event: "unpipe", listener: (src: stream.Readable) => void): this; - prependListener(event: "streamClosed", listener: (code: number) => void): this; - prependListener(event: "timeout", listener: () => void): this; - prependListener(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "aborted", listener: () => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "end", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "finish", listener: () => void): this; - prependOnceListener(event: "frameError", listener: (frameType: number, errorCode: number) => void): this; - prependOnceListener(event: "pipe", listener: (src: stream.Readable) => void): this; - prependOnceListener(event: "unpipe", listener: (src: stream.Readable) => void): this; - prependOnceListener(event: "streamClosed", listener: (code: number) => void): this; - prependOnceListener(event: "timeout", listener: () => void): this; - prependOnceListener(event: "trailers", listener: (trailers: IncomingHttpHeaders, flags: number) => void): this; - } - - export interface ClientHttp2Stream extends Http2Stream { - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - addListener(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - addListener(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "headers", headers: IncomingHttpHeaders, flags: number): boolean; - emit(event: "push", headers: IncomingHttpHeaders, flags: number): boolean; - emit(event: "response", headers: IncomingHttpHeaders, flags: number): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - on(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - on(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - once(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - once(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - prependListener(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - prependListener(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "headers", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - prependOnceListener(event: "push", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - prependOnceListener(event: "response", listener: (headers: IncomingHttpHeaders, flags: number) => void): this; - } - - export interface ServerHttp2Stream extends Http2Stream { - additionalHeaders(headers: OutgoingHttpHeaders): void; - readonly headersSent: boolean; - readonly pushAllowed: boolean; - pushStream(headers: OutgoingHttpHeaders, callback?: (pushStream: ServerHttp2Stream) => void): void; - pushStream(headers: OutgoingHttpHeaders, options?: StreamPriorityOptions, callback?: (pushStream: ServerHttp2Stream) => void): void; - respond(headers?: OutgoingHttpHeaders, options?: ServerStreamResponseOptions): void; - respondWithFD(fd: number, headers?: OutgoingHttpHeaders, options?: ServerStreamFileResponseOptions): void; - respondWithFile(path: string, headers?: OutgoingHttpHeaders, options?: ServerStreamFileResponseOptionsWithError): void; - } - - // Http2Session - - export interface Settings { - headerTableSize?: number; - enablePush?: boolean; - initialWindowSize?: number; - maxFrameSize?: number; - maxConcurrentStreams?: number; - maxHeaderListSize?: number; - } - - export interface ClientSessionRequestOptions { - endStream?: boolean; - exclusive?: boolean; - parent?: number; - weight?: number; - getTrailers?: (trailers: OutgoingHttpHeaders, flags: number) => void; - } - - export interface SessionShutdownOptions { - graceful?: boolean; - errorCode?: number; - lastStreamID?: number; - opaqueData?: Buffer | Uint8Array; - } - - export interface SessionState { - effectiveLocalWindowSize?: number; - effectiveRecvDataLength?: number; - nextStreamID?: number; - localWindowSize?: number; - lastProcStreamID?: number; - remoteWindowSize?: number; - outboundQueueSize?: number; - deflateDynamicTableSize?: number; - inflateDynamicTableSize?: number; - } - - export interface Http2Session extends events.EventEmitter { - destroy(): void; - readonly destroyed: boolean; - readonly localSettings: Settings; - readonly pendingSettingsAck: boolean; - readonly remoteSettings: Settings; - rstStream(stream: Http2Stream, code?: number): void; - setTimeout(msecs: number, callback?: () => void): void; - shutdown(callback?: () => void): void; - shutdown(options: SessionShutdownOptions, callback?: () => void): void; - readonly socket: net.Socket | tls.TLSSocket; - readonly state: SessionState; - priority(stream: Http2Stream, options: StreamPriorityOptions): void; - settings(settings: Settings): void; - readonly type: number; - - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; - addListener(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; - addListener(event: "localSettings", listener: (settings: Settings) => void): this; - addListener(event: "remoteSettings", listener: (settings: Settings) => void): this; - addListener(event: "socketError", listener: (err: Error) => void): this; - addListener(event: "timeout", listener: () => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "frameError", frameType: number, errorCode: number, streamID: number): boolean; - emit(event: "goaway", errorCode: number, lastStreamID: number, opaqueData: Buffer): boolean; - emit(event: "localSettings", settings: Settings): boolean; - emit(event: "remoteSettings", settings: Settings): boolean; - emit(event: "socketError", err: Error): boolean; - emit(event: "timeout"): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "close", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; - on(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; - on(event: "localSettings", listener: (settings: Settings) => void): this; - on(event: "remoteSettings", listener: (settings: Settings) => void): this; - on(event: "socketError", listener: (err: Error) => void): this; - on(event: "timeout", listener: () => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "close", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; - once(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; - once(event: "localSettings", listener: (settings: Settings) => void): this; - once(event: "remoteSettings", listener: (settings: Settings) => void): this; - once(event: "socketError", listener: (err: Error) => void): this; - once(event: "timeout", listener: () => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; - prependListener(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; - prependListener(event: "localSettings", listener: (settings: Settings) => void): this; - prependListener(event: "remoteSettings", listener: (settings: Settings) => void): this; - prependListener(event: "socketError", listener: (err: Error) => void): this; - prependListener(event: "timeout", listener: () => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "frameError", listener: (frameType: number, errorCode: number, streamID: number) => void): this; - prependOnceListener(event: "goaway", listener: (errorCode: number, lastStreamID: number, opaqueData: Buffer) => void): this; - prependOnceListener(event: "localSettings", listener: (settings: Settings) => void): this; - prependOnceListener(event: "remoteSettings", listener: (settings: Settings) => void): this; - prependOnceListener(event: "socketError", listener: (err: Error) => void): this; - prependOnceListener(event: "timeout", listener: () => void): this; - } - - export interface ClientHttp2Session extends Http2Session { - request(headers?: OutgoingHttpHeaders, options?: ClientSessionRequestOptions): ClientHttp2Stream; - - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - addListener(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "connect", session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket): boolean; - emit(event: "stream", stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - on(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - once(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - prependListener(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "connect", listener: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - prependOnceListener(event: "stream", listener: (stream: ClientHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - } - - export interface ServerHttp2Session extends Http2Session { - readonly server: Http2Server | Http2SecureServer; - - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - addListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "connect", session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket): boolean; - emit(event: "stream", stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - on(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - once(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - prependListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "connect", listener: (session: ServerHttp2Session, socket: net.Socket | tls.TLSSocket) => void): this; - prependOnceListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - } - - // Http2Server - - export interface SessionOptions { - maxDeflateDynamicTableSize?: number; - maxReservedRemoteStreams?: number; - maxSendHeaderBlockLength?: number; - paddingStrategy?: number; - peerMaxConcurrentStreams?: number; - selectPadding?: (frameLen: number, maxFrameLen: number) => number; - settings?: Settings; - } - - export type ClientSessionOptions = SessionOptions; - export type ServerSessionOptions = SessionOptions; - - export interface SecureClientSessionOptions extends ClientSessionOptions, tls.ConnectionOptions { } - export interface SecureServerSessionOptions extends ServerSessionOptions, tls.TlsOptions { } - - export interface ServerOptions extends ServerSessionOptions { - allowHTTP1?: boolean; - } - - export interface SecureServerOptions extends SecureServerSessionOptions { - allowHTTP1?: boolean; - } - - export interface Http2Server extends net.Server { - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - addListener(event: "sessionError", listener: (err: Error) => void): this; - addListener(event: "socketError", listener: (err: Error) => void): this; - addListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - addListener(event: "timeout", listener: () => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "request", request: Http2ServerRequest, response: Http2ServerResponse): boolean; - emit(event: "sessionError", err: Error): boolean; - emit(event: "socketError", err: Error): boolean; - emit(event: "stream", stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; - emit(event: "timeout"): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - on(event: "sessionError", listener: (err: Error) => void): this; - on(event: "socketError", listener: (err: Error) => void): this; - on(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - on(event: "timeout", listener: () => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - once(event: "sessionError", listener: (err: Error) => void): this; - once(event: "socketError", listener: (err: Error) => void): this; - once(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - once(event: "timeout", listener: () => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - prependListener(event: "sessionError", listener: (err: Error) => void): this; - prependListener(event: "socketError", listener: (err: Error) => void): this; - prependListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - prependListener(event: "timeout", listener: () => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - prependOnceListener(event: "sessionError", listener: (err: Error) => void): this; - prependOnceListener(event: "socketError", listener: (err: Error) => void): this; - prependOnceListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - prependOnceListener(event: "timeout", listener: () => void): this; - } - - export interface Http2SecureServer extends tls.Server { - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - addListener(event: "sessionError", listener: (err: Error) => void): this; - addListener(event: "socketError", listener: (err: Error) => void): this; - addListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - addListener(event: "timeout", listener: () => void): this; - addListener(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "request", request: Http2ServerRequest, response: Http2ServerResponse): boolean; - emit(event: "sessionError", err: Error): boolean; - emit(event: "socketError", err: Error): boolean; - emit(event: "stream", stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number): boolean; - emit(event: "timeout"): boolean; - emit(event: "unknownProtocol", socket: tls.TLSSocket): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - on(event: "sessionError", listener: (err: Error) => void): this; - on(event: "socketError", listener: (err: Error) => void): this; - on(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - on(event: "timeout", listener: () => void): this; - on(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - once(event: "sessionError", listener: (err: Error) => void): this; - once(event: "socketError", listener: (err: Error) => void): this; - once(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - once(event: "timeout", listener: () => void): this; - once(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - prependListener(event: "sessionError", listener: (err: Error) => void): this; - prependListener(event: "socketError", listener: (err: Error) => void): this; - prependListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - prependListener(event: "timeout", listener: () => void): this; - prependListener(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "request", listener: (request: Http2ServerRequest, response: Http2ServerResponse) => void): this; - prependOnceListener(event: "sessionError", listener: (err: Error) => void): this; - prependOnceListener(event: "socketError", listener: (err: Error) => void): this; - prependOnceListener(event: "stream", listener: (stream: ServerHttp2Stream, headers: IncomingHttpHeaders, flags: number) => void): this; - prependOnceListener(event: "timeout", listener: () => void): this; - prependOnceListener(event: "unknownProtocol", listener: (socket: tls.TLSSocket) => void): this; - } - - export interface Http2ServerRequest extends stream.Readable { - headers: IncomingHttpHeaders; - httpVersion: string; - method: string; - rawHeaders: string[]; - rawTrailers: string[]; - setTimeout(msecs: number, callback?: () => void): void; - socket: net.Socket | tls.TLSSocket; - stream: ServerHttp2Stream; - trailers: IncomingHttpHeaders; - url: string; - - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "aborted", hadError: boolean, code: number): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - } - - export interface Http2ServerResponse extends events.EventEmitter { - addTrailers(trailers: OutgoingHttpHeaders): void; - connection: net.Socket | tls.TLSSocket; - end(callback?: () => void): void; - end(data?: string | Buffer, callback?: () => void): void; - end(data?: string | Buffer, encoding?: string, callback?: () => void): void; - readonly finished: boolean; - getHeader(name: string): string; - getHeaderNames(): string[]; - getHeaders(): OutgoingHttpHeaders; - hasHeader(name: string): boolean; - readonly headersSent: boolean; - removeHeader(name: string): void; - sendDate: boolean; - setHeader(name: string, value: number | string | string[]): void; - setTimeout(msecs: number, callback?: () => void): void; - socket: net.Socket | tls.TLSSocket; - statusCode: number; - statusMessage: ''; - stream: ServerHttp2Stream; - write(chunk: string | Buffer, callback?: (err: Error) => void): boolean; - write(chunk: string | Buffer, encoding?: string, callback?: (err: Error) => void): boolean; - writeContinue(): void; - writeHead(statusCode: number, headers?: OutgoingHttpHeaders): void; - writeHead(statusCode: number, statusMessage?: string, headers?: OutgoingHttpHeaders): void; - createPushResponse(headers: OutgoingHttpHeaders, callback: (err: Error | null, res: Http2ServerResponse) => void): void; - - addListener(event: string, listener: (...args: any[]) => void): this; - addListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "error", listener: (error: Error) => void): this; - addListener(event: "finish", listener: () => void): this; - - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: "aborted", hadError: boolean, code: number): boolean; - emit(event: "close"): boolean; - emit(event: "drain"): boolean; - emit(event: "error", error: Error): boolean; - emit(event: "finish"): boolean; - - on(event: string, listener: (...args: any[]) => void): this; - on(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - on(event: "close", listener: () => void): this; - on(event: "drain", listener: () => void): this; - on(event: "error", listener: (error: Error) => void): this; - on(event: "finish", listener: () => void): this; - - once(event: string, listener: (...args: any[]) => void): this; - once(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - once(event: "close", listener: () => void): this; - once(event: "drain", listener: () => void): this; - once(event: "error", listener: (error: Error) => void): this; - once(event: "finish", listener: () => void): this; - - prependListener(event: string, listener: (...args: any[]) => void): this; - prependListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "error", listener: (error: Error) => void): this; - prependListener(event: "finish", listener: () => void): this; - - prependOnceListener(event: string, listener: (...args: any[]) => void): this; - prependOnceListener(event: "aborted", listener: (hadError: boolean, code: number) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "error", listener: (error: Error) => void): this; - prependOnceListener(event: "finish", listener: () => void): this; - } - - // Public API - - export namespace constants { - export const NGHTTP2_SESSION_SERVER: number; - export const NGHTTP2_SESSION_CLIENT: number; - export const NGHTTP2_STREAM_STATE_IDLE: number; - export const NGHTTP2_STREAM_STATE_OPEN: number; - export const NGHTTP2_STREAM_STATE_RESERVED_LOCAL: number; - export const NGHTTP2_STREAM_STATE_RESERVED_REMOTE: number; - export const NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL: number; - export const NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE: number; - export const NGHTTP2_STREAM_STATE_CLOSED: number; - export const NGHTTP2_NO_ERROR: number; - export const NGHTTP2_PROTOCOL_ERROR: number; - export const NGHTTP2_INTERNAL_ERROR: number; - export const NGHTTP2_FLOW_CONTROL_ERROR: number; - export const NGHTTP2_SETTINGS_TIMEOUT: number; - export const NGHTTP2_STREAM_CLOSED: number; - export const NGHTTP2_FRAME_SIZE_ERROR: number; - export const NGHTTP2_REFUSED_STREAM: number; - export const NGHTTP2_CANCEL: number; - export const NGHTTP2_COMPRESSION_ERROR: number; - export const NGHTTP2_CONNECT_ERROR: number; - export const NGHTTP2_ENHANCE_YOUR_CALM: number; - export const NGHTTP2_INADEQUATE_SECURITY: number; - export const NGHTTP2_HTTP_1_1_REQUIRED: number; - export const NGHTTP2_ERR_FRAME_SIZE_ERROR: number; - export const NGHTTP2_FLAG_NONE: number; - export const NGHTTP2_FLAG_END_STREAM: number; - export const NGHTTP2_FLAG_END_HEADERS: number; - export const NGHTTP2_FLAG_ACK: number; - export const NGHTTP2_FLAG_PADDED: number; - export const NGHTTP2_FLAG_PRIORITY: number; - export const DEFAULT_SETTINGS_HEADER_TABLE_SIZE: number; - export const DEFAULT_SETTINGS_ENABLE_PUSH: number; - export const DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE: number; - export const DEFAULT_SETTINGS_MAX_FRAME_SIZE: number; - export const MAX_MAX_FRAME_SIZE: number; - export const MIN_MAX_FRAME_SIZE: number; - export const MAX_INITIAL_WINDOW_SIZE: number; - export const NGHTTP2_DEFAULT_WEIGHT: number; - export const NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: number; - export const NGHTTP2_SETTINGS_ENABLE_PUSH: number; - export const NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: number; - export const NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: number; - export const NGHTTP2_SETTINGS_MAX_FRAME_SIZE: number; - export const NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: number; - export const PADDING_STRATEGY_NONE: number; - export const PADDING_STRATEGY_MAX: number; - export const PADDING_STRATEGY_CALLBACK: number; - export const HTTP2_HEADER_STATUS: string; - export const HTTP2_HEADER_METHOD: string; - export const HTTP2_HEADER_AUTHORITY: string; - export const HTTP2_HEADER_SCHEME: string; - export const HTTP2_HEADER_PATH: string; - export const HTTP2_HEADER_ACCEPT_CHARSET: string; - export const HTTP2_HEADER_ACCEPT_ENCODING: string; - export const HTTP2_HEADER_ACCEPT_LANGUAGE: string; - export const HTTP2_HEADER_ACCEPT_RANGES: string; - export const HTTP2_HEADER_ACCEPT: string; - export const HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN: string; - export const HTTP2_HEADER_AGE: string; - export const HTTP2_HEADER_ALLOW: string; - export const HTTP2_HEADER_AUTHORIZATION: string; - export const HTTP2_HEADER_CACHE_CONTROL: string; - export const HTTP2_HEADER_CONNECTION: string; - export const HTTP2_HEADER_CONTENT_DISPOSITION: string; - export const HTTP2_HEADER_CONTENT_ENCODING: string; - export const HTTP2_HEADER_CONTENT_LANGUAGE: string; - export const HTTP2_HEADER_CONTENT_LENGTH: string; - export const HTTP2_HEADER_CONTENT_LOCATION: string; - export const HTTP2_HEADER_CONTENT_MD5: string; - export const HTTP2_HEADER_CONTENT_RANGE: string; - export const HTTP2_HEADER_CONTENT_TYPE: string; - export const HTTP2_HEADER_COOKIE: string; - export const HTTP2_HEADER_DATE: string; - export const HTTP2_HEADER_ETAG: string; - export const HTTP2_HEADER_EXPECT: string; - export const HTTP2_HEADER_EXPIRES: string; - export const HTTP2_HEADER_FROM: string; - export const HTTP2_HEADER_HOST: string; - export const HTTP2_HEADER_IF_MATCH: string; - export const HTTP2_HEADER_IF_MODIFIED_SINCE: string; - export const HTTP2_HEADER_IF_NONE_MATCH: string; - export const HTTP2_HEADER_IF_RANGE: string; - export const HTTP2_HEADER_IF_UNMODIFIED_SINCE: string; - export const HTTP2_HEADER_LAST_MODIFIED: string; - export const HTTP2_HEADER_LINK: string; - export const HTTP2_HEADER_LOCATION: string; - export const HTTP2_HEADER_MAX_FORWARDS: string; - export const HTTP2_HEADER_PREFER: string; - export const HTTP2_HEADER_PROXY_AUTHENTICATE: string; - export const HTTP2_HEADER_PROXY_AUTHORIZATION: string; - export const HTTP2_HEADER_RANGE: string; - export const HTTP2_HEADER_REFERER: string; - export const HTTP2_HEADER_REFRESH: string; - export const HTTP2_HEADER_RETRY_AFTER: string; - export const HTTP2_HEADER_SERVER: string; - export const HTTP2_HEADER_SET_COOKIE: string; - export const HTTP2_HEADER_STRICT_TRANSPORT_SECURITY: string; - export const HTTP2_HEADER_TRANSFER_ENCODING: string; - export const HTTP2_HEADER_TE: string; - export const HTTP2_HEADER_UPGRADE: string; - export const HTTP2_HEADER_USER_AGENT: string; - export const HTTP2_HEADER_VARY: string; - export const HTTP2_HEADER_VIA: string; - export const HTTP2_HEADER_WWW_AUTHENTICATE: string; - export const HTTP2_HEADER_HTTP2_SETTINGS: string; - export const HTTP2_HEADER_KEEP_ALIVE: string; - export const HTTP2_HEADER_PROXY_CONNECTION: string; - export const HTTP2_METHOD_ACL: string; - export const HTTP2_METHOD_BASELINE_CONTROL: string; - export const HTTP2_METHOD_BIND: string; - export const HTTP2_METHOD_CHECKIN: string; - export const HTTP2_METHOD_CHECKOUT: string; - export const HTTP2_METHOD_CONNECT: string; - export const HTTP2_METHOD_COPY: string; - export const HTTP2_METHOD_DELETE: string; - export const HTTP2_METHOD_GET: string; - export const HTTP2_METHOD_HEAD: string; - export const HTTP2_METHOD_LABEL: string; - export const HTTP2_METHOD_LINK: string; - export const HTTP2_METHOD_LOCK: string; - export const HTTP2_METHOD_MERGE: string; - export const HTTP2_METHOD_MKACTIVITY: string; - export const HTTP2_METHOD_MKCALENDAR: string; - export const HTTP2_METHOD_MKCOL: string; - export const HTTP2_METHOD_MKREDIRECTREF: string; - export const HTTP2_METHOD_MKWORKSPACE: string; - export const HTTP2_METHOD_MOVE: string; - export const HTTP2_METHOD_OPTIONS: string; - export const HTTP2_METHOD_ORDERPATCH: string; - export const HTTP2_METHOD_PATCH: string; - export const HTTP2_METHOD_POST: string; - export const HTTP2_METHOD_PRI: string; - export const HTTP2_METHOD_PROPFIND: string; - export const HTTP2_METHOD_PROPPATCH: string; - export const HTTP2_METHOD_PUT: string; - export const HTTP2_METHOD_REBIND: string; - export const HTTP2_METHOD_REPORT: string; - export const HTTP2_METHOD_SEARCH: string; - export const HTTP2_METHOD_TRACE: string; - export const HTTP2_METHOD_UNBIND: string; - export const HTTP2_METHOD_UNCHECKOUT: string; - export const HTTP2_METHOD_UNLINK: string; - export const HTTP2_METHOD_UNLOCK: string; - export const HTTP2_METHOD_UPDATE: string; - export const HTTP2_METHOD_UPDATEREDIRECTREF: string; - export const HTTP2_METHOD_VERSION_CONTROL: string; - export const HTTP_STATUS_CONTINUE: number; - export const HTTP_STATUS_SWITCHING_PROTOCOLS: number; - export const HTTP_STATUS_PROCESSING: number; - export const HTTP_STATUS_OK: number; - export const HTTP_STATUS_CREATED: number; - export const HTTP_STATUS_ACCEPTED: number; - export const HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION: number; - export const HTTP_STATUS_NO_CONTENT: number; - export const HTTP_STATUS_RESET_CONTENT: number; - export const HTTP_STATUS_PARTIAL_CONTENT: number; - export const HTTP_STATUS_MULTI_STATUS: number; - export const HTTP_STATUS_ALREADY_REPORTED: number; - export const HTTP_STATUS_IM_USED: number; - export const HTTP_STATUS_MULTIPLE_CHOICES: number; - export const HTTP_STATUS_MOVED_PERMANENTLY: number; - export const HTTP_STATUS_FOUND: number; - export const HTTP_STATUS_SEE_OTHER: number; - export const HTTP_STATUS_NOT_MODIFIED: number; - export const HTTP_STATUS_USE_PROXY: number; - export const HTTP_STATUS_TEMPORARY_REDIRECT: number; - export const HTTP_STATUS_PERMANENT_REDIRECT: number; - export const HTTP_STATUS_BAD_REQUEST: number; - export const HTTP_STATUS_UNAUTHORIZED: number; - export const HTTP_STATUS_PAYMENT_REQUIRED: number; - export const HTTP_STATUS_FORBIDDEN: number; - export const HTTP_STATUS_NOT_FOUND: number; - export const HTTP_STATUS_METHOD_NOT_ALLOWED: number; - export const HTTP_STATUS_NOT_ACCEPTABLE: number; - export const HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED: number; - export const HTTP_STATUS_REQUEST_TIMEOUT: number; - export const HTTP_STATUS_CONFLICT: number; - export const HTTP_STATUS_GONE: number; - export const HTTP_STATUS_LENGTH_REQUIRED: number; - export const HTTP_STATUS_PRECONDITION_FAILED: number; - export const HTTP_STATUS_PAYLOAD_TOO_LARGE: number; - export const HTTP_STATUS_URI_TOO_LONG: number; - export const HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE: number; - export const HTTP_STATUS_RANGE_NOT_SATISFIABLE: number; - export const HTTP_STATUS_EXPECTATION_FAILED: number; - export const HTTP_STATUS_TEAPOT: number; - export const HTTP_STATUS_MISDIRECTED_REQUEST: number; - export const HTTP_STATUS_UNPROCESSABLE_ENTITY: number; - export const HTTP_STATUS_LOCKED: number; - export const HTTP_STATUS_FAILED_DEPENDENCY: number; - export const HTTP_STATUS_UNORDERED_COLLECTION: number; - export const HTTP_STATUS_UPGRADE_REQUIRED: number; - export const HTTP_STATUS_PRECONDITION_REQUIRED: number; - export const HTTP_STATUS_TOO_MANY_REQUESTS: number; - export const HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE: number; - export const HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS: number; - export const HTTP_STATUS_INTERNAL_SERVER_ERROR: number; - export const HTTP_STATUS_NOT_IMPLEMENTED: number; - export const HTTP_STATUS_BAD_GATEWAY: number; - export const HTTP_STATUS_SERVICE_UNAVAILABLE: number; - export const HTTP_STATUS_GATEWAY_TIMEOUT: number; - export const HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED: number; - export const HTTP_STATUS_VARIANT_ALSO_NEGOTIATES: number; - export const HTTP_STATUS_INSUFFICIENT_STORAGE: number; - export const HTTP_STATUS_LOOP_DETECTED: number; - export const HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED: number; - export const HTTP_STATUS_NOT_EXTENDED: number; - export const HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED: number; - } - - export function getDefaultSettings(): Settings; - export function getPackedSettings(settings: Settings): Settings; - export function getUnpackedSettings(buf: Buffer | Uint8Array): Settings; - - export function createServer(onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2Server; - export function createServer(options: ServerOptions, onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2Server; - - export function createSecureServer(onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2SecureServer; - export function createSecureServer(options: SecureServerOptions, onRequestHandler?: (request: Http2ServerRequest, response: Http2ServerResponse) => void): Http2SecureServer; - - export function connect(authority: string | url.URL, listener?: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): ClientHttp2Session; - export function connect(authority: string | url.URL, options?: ClientSessionOptions | SecureClientSessionOptions, listener?: (session: ClientHttp2Session, socket: net.Socket | tls.TLSSocket) => void): ClientHttp2Session; -} - -declare module "perf_hooks" { - export interface PerformanceEntry { - /** - * The total number of milliseconds elapsed for this entry. - * This value will not be meaningful for all Performance Entry types. - */ - readonly duration: number; - - /** - * The name of the performance entry. - */ - readonly name: string; - - /** - * The high resolution millisecond timestamp marking the starting time of the Performance Entry. - */ - readonly startTime: number; - - /** - * The type of the performance entry. - * Currently it may be one of: 'node', 'mark', 'measure', 'gc', or 'function'. - */ - readonly entryType: string; - - /** - * When performanceEntry.entryType is equal to 'gc', the performance.kind property identifies - * the type of garbage collection operation that occurred. - * The value may be one of perf_hooks.constants. - */ - readonly kind?: number; - } - - export interface PerformanceNodeTiming extends PerformanceEntry { - /** - * The high resolution millisecond timestamp at which the Node.js process completed bootstrap. - */ - readonly bootstrapComplete: number; - - /** - * The high resolution millisecond timestamp at which cluster processing ended. - */ - readonly clusterSetupEnd: number; - - /** - * The high resolution millisecond timestamp at which cluster processing started. - */ - readonly clusterSetupStart: number; - - /** - * The high resolution millisecond timestamp at which the Node.js event loop exited. - */ - readonly loopExit: number; - - /** - * The high resolution millisecond timestamp at which the Node.js event loop started. - */ - readonly loopStart: number; - - /** - * The high resolution millisecond timestamp at which main module load ended. - */ - readonly moduleLoadEnd: number; - - /** - * The high resolution millisecond timestamp at which main module load started. - */ - readonly moduleLoadStart: number; - - /** - * The high resolution millisecond timestamp at which the Node.js process was initialized. - */ - readonly nodeStart: number; - - /** - * The high resolution millisecond timestamp at which preload module load ended. - */ - readonly preloadModuleLoadEnd: number; - - /** - * The high resolution millisecond timestamp at which preload module load started. - */ - readonly preloadModuleLoadStart: number; - - /** - * The high resolution millisecond timestamp at which third_party_main processing ended. - */ - readonly thirdPartyMainEnd: number; - - /** - * The high resolution millisecond timestamp at which third_party_main processing started. - */ - readonly thirdPartyMainStart: number; - - /** - * The high resolution millisecond timestamp at which the V8 platform was initialized. - */ - readonly v8Start: number; - } - - export interface Performance { - /** - * If name is not provided, removes all PerformanceFunction objects from the Performance Timeline. - * If name is provided, removes entries with name. - * @param name - */ - clearFunctions(name?: string): void; - - /** - * If name is not provided, removes all PerformanceMark objects from the Performance Timeline. - * If name is provided, removes only the named mark. - * @param name - */ - clearMarks(name?: string): void; - - /** - * If name is not provided, removes all PerformanceMeasure objects from the Performance Timeline. - * If name is provided, removes only objects whose performanceEntry.name matches name. - */ - clearMeasures(name?: string): void; - - /** - * Returns a list of all PerformanceEntry objects in chronological order with respect to performanceEntry.startTime. - * @return list of all PerformanceEntry objects - */ - getEntries(): PerformanceEntry[]; - - /** - * Returns a list of all PerformanceEntry objects in chronological order with respect to performanceEntry.startTime - * whose performanceEntry.name is equal to name, and optionally, whose performanceEntry.entryType is equal to type. - * @param name - * @param type - * @return list of all PerformanceEntry objects - */ - getEntriesByName(name: string, type?: string): PerformanceEntry[]; - - /** - * Returns a list of all PerformanceEntry objects in chronological order with respect to performanceEntry.startTime - * whose performanceEntry.entryType is equal to type. - * @param type - * @return list of all PerformanceEntry objects - */ - getEntriesByType(type: string): PerformanceEntry[]; - - /** - * Creates a new PerformanceMark entry in the Performance Timeline. - * A PerformanceMark is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'mark', - * and whose performanceEntry.duration is always 0. - * Performance marks are used to mark specific significant moments in the Performance Timeline. - * @param name - */ - mark(name?: string): void; - - /** - * Creates a new PerformanceMeasure entry in the Performance Timeline. - * A PerformanceMeasure is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'measure', - * and whose performanceEntry.duration measures the number of milliseconds elapsed since startMark and endMark. - * - * The startMark argument may identify any existing PerformanceMark in the the Performance Timeline, or may identify - * any of the timestamp properties provided by the PerformanceNodeTiming class. If the named startMark does not exist, - * then startMark is set to timeOrigin by default. - * - * The endMark argument must identify any existing PerformanceMark in the the Performance Timeline or any of the timestamp - * properties provided by the PerformanceNodeTiming class. If the named endMark does not exist, an error will be thrown. - * @param name - * @param startMark - * @param endMark - */ - measure(name: string, startMark: string, endMark: string): void; - - /** - * An instance of the PerformanceNodeTiming class that provides performance metrics for specific Node.js operational milestones. - */ - readonly nodeTiming: PerformanceNodeTiming; - - /** - * @return the current high resolution millisecond timestamp - */ - now(): number; - - /** - * The timeOrigin specifies the high resolution millisecond timestamp from which all performance metric durations are measured. - */ - readonly timeOrigin: number; - - /** - * Wraps a function within a new function that measures the running time of the wrapped function. - * A PerformanceObserver must be subscribed to the 'function' event type in order for the timing details to be accessed. - * @param fn - */ - timerify any>(fn: T): T; - } - - export interface PerformanceObserverEntryList { - /** - * @return a list of PerformanceEntry objects in chronological order with respect to performanceEntry.startTime. - */ - getEntries(): PerformanceEntry[]; - - /** - * @return a list of PerformanceEntry objects in chronological order with respect to performanceEntry.startTime - * whose performanceEntry.name is equal to name, and optionally, whose performanceEntry.entryType is equal to type. - */ - getEntriesByName(name: string, type?: string): PerformanceEntry[]; - - /** - * @return Returns a list of PerformanceEntry objects in chronological order with respect to performanceEntry.startTime - * whose performanceEntry.entryType is equal to type. - */ - getEntriesByType(type: string): PerformanceEntry[]; - } - - export type PerformanceObserverCallback = (list: PerformanceObserverEntryList, observer: PerformanceObserver) => void; - - export class PerformanceObserver { - constructor(callback: PerformanceObserverCallback); - - /** - * Disconnects the PerformanceObserver instance from all notifications. - */ - disconnect(): void; - - /** - * Subscribes the PerformanceObserver instance to notifications of new PerformanceEntry instances identified by options.entryTypes. - * When options.buffered is false, the callback will be invoked once for every PerformanceEntry instance. - * Property buffered defaults to false. - * @param options - */ - observe(options: { entryTypes: string[], buffered?: boolean }): void; - } - - export namespace constants { - export const NODE_PERFORMANCE_GC_MAJOR: number; - export const NODE_PERFORMANCE_GC_MINOR: number; - export const NODE_PERFORMANCE_GC_INCREMENTAL: number; - export const NODE_PERFORMANCE_GC_WEAKCB: number; - } - - const performance: Performance; -} \ No newline at end of file diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 55b001b91b4..cd7e4aad59e 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1116,7 +1116,7 @@ export function windowOpenNoOpener(url: string): void { } else { let newTab = window.open(); if (newTab) { - newTab.opener = null; + (newTab as any).opener = null; newTab.location.href = url; } } diff --git a/src/vs/base/browser/event.ts b/src/vs/base/browser/event.ts index 6cf13a62f44..25b85a6807d 100644 --- a/src/vs/base/browser/event.ts +++ b/src/vs/base/browser/event.ts @@ -19,7 +19,6 @@ export interface IDomEvent { (element: EventHandler, type: 'MSGotPointerCapture', useCapture?: boolean): _Event; (element: EventHandler, type: 'MSInertiaStart', useCapture?: boolean): _Event; (element: EventHandler, type: 'MSLostPointerCapture', useCapture?: boolean): _Event; - (element: EventHandler, type: 'MSManipulationStateChanged', useCapture?: boolean): _Event; (element: EventHandler, type: 'MSPointerCancel', useCapture?: boolean): _Event; (element: EventHandler, type: 'MSPointerDown', useCapture?: boolean): _Event; (element: EventHandler, type: 'MSPointerEnter', useCapture?: boolean): _Event; diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index 3e11ab520f9..4155453489f 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -229,17 +229,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate= 0 && selected < this.options.length) { - this.select(selected); - } else if (selected > this.options.length - 1) { - // This could make client out of sync with the select - this.select(this.options.length - 1); - console.error('selectBoxCustom: setOptions selected exceeds options length'); - } else if (selected < 0) { - this.selected = 0; - } + this.select(selected); } } @@ -247,6 +237,10 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate= 0 && index < this.options.length) { this.selected = index; + } else if (index > this.options.length - 1) { + // Adjust index to end of list + // This could make client out of sync with the select + this.select(this.options.length - 1); } else if (this.selected < 0) { this.selected = 0; } @@ -363,12 +357,6 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate this.options.length - 1 || !this.selectList.length) { - console.error('selectBoxCustom: showSelectDropDown this.select exceeds options length or empty list'); - return; - } - this._isVisible = true; this.cloneElementFont(this.selectElement, this.selectDropDownContainer); this.contextViewProvider.showContextView({ diff --git a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts index a04587b8685..c16bd47e0f3 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts @@ -84,23 +84,17 @@ export class SelectBoxNative implements ISelectBoxDelegate { } if (selected !== undefined) { - // Guard against out of bounds selected values - // Cannot currently return error, set selected within range - if (selected >= 0 && selected < this.options.length) { - this.select(selected); - } else if (selected > this.options.length - 1) { - // This could make client out of sync with the select - this.select(this.options.length - 1); - console.error('selectBoxNative: setOptions selected exceeds options length'); - } else if (selected < 0) { - this.selected = 0; - } + this.select(selected); } } public select(index: number): void { if (index >= 0 && index < this.options.length) { this.selected = index; + } else if (index > this.options.length - 1) { + // Adjust index to end of list + // This could make client out of sync with the select + this.select(this.options.length - 1); } else if (this.selected < 0) { this.selected = 0; } diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 14900a32bff..42e7a5447a6 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -82,12 +82,6 @@ export function readlink(path: string): TPromise { return nfcall(fs.readlink, path); } -export function touch(path: string): TPromise { - const now = Date.now() / 1000; // the value should be a Unix timestamp in seconds - - return nfcall(fs.utimes, path, now, now); -} - export function truncate(path: string, len: number): TPromise { return nfcall(fs.truncate, path, len); } diff --git a/src/vs/base/node/ps-win.ps1 b/src/vs/base/node/ps-win.ps1 deleted file mode 100644 index b98ad7b42c5..00000000000 --- a/src/vs/base/node/ps-win.ps1 +++ /dev/null @@ -1,183 +0,0 @@ -################################################################################################ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -################################################################################################ - -Param( - [string]$ProcessName = "code.exe", - [int]$MaxSamples = 10 -) - -$processLength = "process(".Length - -function Get-MachineInfo { - $model = (Get-WmiObject -Class Win32_Processor).Name - $memory = (Get-WmiObject -Class Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1MB - $wmi_cs = Get-WmiObject -Class Win32_ComputerSystem - return @{ - "type" = "machineInfo" - "model" = $model - "processors" = $wmi_cs.NumberOfProcessors - "logicalProcessors" = $wmi_cs.NumberOfLogicalProcessors - "totalMemory" = $memory - - } -} -$machineInfo = Get-MachineInfo - -function Get-MachineState { - $proc = Get-WmiObject Win32_Processor - $os = Get-WmiObject win32_OperatingSystem - return @{ - "type" = 'machineState' - "cpuLoad" = $proc.LoadPercentage - "handles" = (Get-Process | Measure-Object Handles -Sum).Sum - "memory" = @{ - "total" = $os.TotalVisibleMemorySize - "free" = $os.FreePhysicalMemory - "swapTotal" = $os.TotalVirtualMemorySize - "swapFree" = $os.FreeVirtualMemory - } - } -} -$machineState = Get-MachineState - -$processId2CpuLoad = @{} -function Get-PerformanceCounters ($logicalProcessors) { - $counterError - # In a first round we get the performance counters and the process ids. - $counters = (Get-Counter ("\Process(*)\% Processor Time", "\Process(*)\ID Process") -ErrorAction SilentlyContinue).CounterSamples - $processKey2Id = @{} - foreach ($counter in $counters) { - if ($counter.Status -ne 0) { - continue - } - $path = $counter.path; - $segments = $path.Split("\"); - $kind = $segments[4]; - $processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1) - if ($kind -eq "id process") { - $processKey2Id[$processKey] = [uint32]$counter.CookedValue - } - } - foreach ($counter in $counters) { - if ($counter.Status -ne 0) { - continue - } - $path = $counter.path; - $segments = $path.Split("\"); - $kind = $segments[4]; - $processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1) - if ($kind -eq "% processor time") { - $array = New-Object double[] ($MaxSamples + 1) - $array[0] = ($counter.CookedValue / $logicalProcessors) - $processId = $processKey2Id[$processKey] - if ($processId) { - $processId2CpuLoad[$processId] = $array - } - } - } - # Now lets sample another 10 times but only the processor time - $samples = Get-Counter "\Process(*)\% Processor Time" -SampleInterval 1 -MaxSamples $MaxSamples -ErrorAction SilentlyContinue - for ($s = 0; $s -lt $samples.Count; $s++) { - $counters = $samples[$s].CounterSamples; - foreach ($counter in $counters) { - if ($counter.Status -ne 0) { - continue - } - $path = $counter.path; - $segments = $path.Split("\"); - $processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1) - $processKey = $processKey2Id[$processKey]; - if ($processKey) { - $processId2CpuLoad[$processKey][$s + 1] = ($counter.CookedValue / $logicalProcessors) - } - } - } -} -Get-PerformanceCounters -logicalProcessors $machineInfo.logicalProcessors - -$topElements = New-Object PSObject[] $processId2CpuLoad.Keys.Count; -$index = 0; -foreach ($key in $processId2CpuLoad.Keys) { - $obj = [PSCustomObject]@{ - ProcessId = $key - Load = ($processId2CpuLoad[$key] | Measure-Object -Sum).Sum / ($MaxSamples + 1) - } - $topElements[$index] = $obj - $index++ -} -$topElements = $topElements | Sort-Object Load -Descending - -# Get all code processes -$codeProcesses = @{} -foreach ($item in Get-WmiObject Win32_Process -Filter "name = '$ProcessName'") { - $codeProcesses[$item.ProcessId] = $item -} -foreach ($item in Get-WmiObject Win32_Process -Filter "name = 'codeHelper.exe'") { - $codeProcesses[$item.ProcessId] = $item -} -$otherProcesses = @{} -foreach ($item in Get-WmiObject Win32_Process -Filter "name Like '%'") { - if (!($codeProcesses.Contains($item.ProcessId))) { - $otherProcesses[$item.ProcessId] = $item - } -} -$modified = $false -do { - $toDelete = @() - $modified = $false - foreach ($item in $otherProcesses.Values) { - if ($codeProcesses.Contains([uint32]$item.ParentProcessId)) { - $codeProcesses[$item.ProcessId] = $item; - $toDelete += $item - } - } - foreach ($item in $toDelete) { - $otherProcesses.Remove([uint32]$item.ProcessId) - $modified = $true - } -} while ($modified) - -$result = New-Object PSObject[] (2 + [math]::Min(5, $topElements.Count) + $codeProcesses.Count) -$result[0] = $machineInfo -$result[1] = $machineState -$index = 2; -for($i = 0; $i -lt 5 -and $i -lt $topElements.Count; $i++) { - $element = $topElements[$i] - $item = $codeProcesses[[uint32]$element.ProcessId] - if (!$item) { - $item = $otherProcesses[[uint32]$element.ProcessId] - } - if ($item) { - $cpuLoad = $processId2CpuLoad[[uint32]$item.ProcessId] | % { [pscustomobject] $_ } - $result[$index] = [pscustomobject]@{ - "type" = "topProcess" - "name" = $item.Name - "processId" = $item.ProcessId - "parentProcessId" = $item.ParentProcessId - "commandLine" = $item.CommandLine - "handles" = $item.HandleCount - "cpuLoad" = $cpuLoad - "workingSetSize" = $item.WorkingSetSize - } - $index++ - } -} -foreach ($item in $codeProcesses.Values) { - # we need to convert this otherwise to JSON with create a value, count object and not an inline array - $cpuLoad = $processId2CpuLoad[[uint32]$item.ProcessId] | % { [pscustomobject] $_ } - $result[$index] = [pscustomobject]@{ - "type" = "processInfo" - "name" = $item.Name - "processId" = $item.ProcessId - "parentProcessId" = $item.ParentProcessId - "commandLine" = $item.CommandLine - "handles" = $item.HandleCount - "cpuLoad" = $cpuLoad - "workingSetSize" = $item.WorkingSetSize - } - $index++ -} - -$result | ConvertTo-Json -Depth 99 diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index 9935e90db48..c47cbf189a8 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -5,10 +5,7 @@ 'use strict'; -import { spawn, exec } from 'child_process'; -import * as path from 'path'; -import * as nls from 'vs/nls'; -import URI from 'vs/base/common/uri'; +import { exec } from 'child_process'; export interface ProcessItem { name: string; @@ -121,32 +118,6 @@ export function listProcesses(rootPid: number): Promise { if (process.platform === 'win32') { - console.log(nls.localize('collecting', 'Collecting CPU and memory information. This might take a couple of seconds.')); - - interface ProcessInfo { - type: 'processInfo'; - name: string; - processId: number; - parentProcessId: number; - commandLine: string; - handles: number; - cpuLoad: number[]; - workingSetSize: number; - } - - interface TopProcess { - type: 'topProcess'; - name: string; - processId: number; - parentProcessId: number; - commandLine: string; - handles: number; - cpuLoad: number[]; - workingSetSize: number; - } - - type Item = ProcessInfo | TopProcess; - const cleanUNCPrefix = (value: string): string => { if (value.indexOf('\\\\?\\') === 0) { return value.substr(4); @@ -161,75 +132,45 @@ export function listProcesses(rootPid: number): Promise { } }; - const execMain = path.basename(process.execPath); - const script = URI.parse(require.toUrl('vs/base/node/ps-win.ps1')).fsPath; - const commandLine = `& {& '${script}' -ProcessName '${execMain}' -MaxSamples 3}`; - const cmd = spawn('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', commandLine]); - - let stdout = ''; - let stderr = ''; - cmd.stdout.on('data', data => { - stdout += data.toString(); - }); - - cmd.stderr.on('data', data => { - stderr += data.toString(); - }); - - cmd.on('exit', () => { - if (stderr.length > 0) { - reject(new Error(stderr)); - return; - } - let processItems: Map = new Map(); - try { - const items: Item[] = JSON.parse(stdout); - for (const item of items) { - if (item.type === 'processInfo') { - let load = 0; - if (item.cpuLoad) { - for (let value of item.cpuLoad) { - load += value; - } - load = load / item.cpuLoad.length; - } else { - load = -1; - } - let commandLine = cleanUNCPrefix(item.commandLine); - processItems.set(item.processId, { + (import('windows-process-tree')).then(windowsProcessTree => { + windowsProcessTree.getProcessList(rootPid, (processList) => { + windowsProcessTree.getProcessCpuUsage(processList, (completeProcessList) => { + const processItems: Map = new Map(); + completeProcessList.forEach(process => { + const commandLine = cleanUNCPrefix(process.commandLine); + processItems.set(process.pid, { name: findName(commandLine), cmd: commandLine, - pid: item.processId, - ppid: item.parentProcessId, - load: load, - mem: item.workingSetSize + pid: process.pid, + ppid: process.ppid, + load: process.cpu, + mem: process.memory }); - } - } - rootItem = processItems.get(rootPid); - if (rootItem) { - processItems.forEach(item => { - let parent = processItems.get(item.ppid); - if (parent) { - if (!parent.children) { - parent.children = []; + }); + + rootItem = processItems.get(rootPid); + if (rootItem) { + processItems.forEach(item => { + let parent = processItems.get(item.ppid); + if (parent) { + if (!parent.children) { + parent.children = []; + } + parent.children.push(item); } - parent.children.push(item); - } - }); - processItems.forEach(item => { - if (item.children) { - item.children = item.children.sort((a, b) => a.pid - b.pid); - } - }); - resolve(rootItem); - } else { - reject(new Error(`Root process ${rootPid} not found`)); - } - } catch (error) { - console.log(stdout); - reject(error); - } + }); + + processItems.forEach(item => { + if (item.children) { + item.children = item.children.sort((a, b) => a.pid - b.pid); + } + }); + resolve(rootItem); + } else { + reject(new Error(`Root process ${rootPid} not found`)); + } + }); + }, windowsProcessTree.ProcessDataFlag.CommandLine | windowsProcessTree.ProcessDataFlag.Memory); }); } else { // OS X & Linux diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 6662a4d20e4..d1a8bfab221 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -59,14 +59,11 @@ import { IssueChannel } from 'vs/platform/issue/common/issueIpc'; import { IssueService } from 'vs/platform/issue/electron-main/issueService'; import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; -import { join } from 'path'; -import { copy } from 'vs/base/node/pfs'; import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener'; export class CodeApplication { private static readonly MACHINE_ID_KEY = 'telemetry.machineId'; - private static readonly LOCAL_STORAGE_BACKED_UP_KEY = 'localStorage.backedUp'; private toDispose: IDisposable[]; private windowsMainService: IWindowsMainService; @@ -264,43 +261,38 @@ export class CodeApplication { this.logService.debug(`from: ${this.environmentService.appRoot}`); this.logService.debug('args:', this.environmentService.args); - // Backup local storage (TODO@Ben remove me after a while) - this.logService.trace('Backing up localStorage if needed...'); - return this.backupLocalStorage().then(() => { + // Make sure we associate the program with the app user model id + // This will help Windows to associate the running program with + // any shortcut that is pinned to the taskbar and prevent showing + // two icons in the taskbar for the same app. + if (platform.isWindows && product.win32AppUserModelId) { + app.setAppUserModelId(product.win32AppUserModelId); + } - // Make sure we associate the program with the app user model id - // This will help Windows to associate the running program with - // any shortcut that is pinned to the taskbar and prevent showing - // two icons in the taskbar for the same app. - if (platform.isWindows && product.win32AppUserModelId) { - app.setAppUserModelId(product.win32AppUserModelId); - } + // Create Electron IPC Server + this.electronIpcServer = new ElectronIPCServer(); - // Create Electron IPC Server - this.electronIpcServer = new ElectronIPCServer(); + // Resolve unique machine ID + this.logService.trace('Resolving machine identifier...'); + return this.resolveMachineId().then(machineId => { + this.logService.trace(`Resolved machine identifier: ${machineId}`); - // Resolve unique machine ID - this.logService.trace('Resolving machine identifier...'); - return this.resolveMachineId().then(machineId => { - this.logService.trace(`Resolved machine identifier: ${machineId}`); + // Spawn shared process + this.sharedProcess = new SharedProcess(this.environmentService, this.lifecycleService, this.logService, machineId, this.userEnv); + this.sharedProcessClient = this.sharedProcess.whenReady().then(() => connect(this.environmentService.sharedIPCHandle, 'main')); - // Spawn shared process - this.sharedProcess = new SharedProcess(this.environmentService, this.lifecycleService, this.logService, machineId, this.userEnv); - this.sharedProcessClient = this.sharedProcess.whenReady().then(() => connect(this.environmentService.sharedIPCHandle, 'main')); + // Services + const appInstantiationService = this.initServices(machineId); - // Services - const appInstantiationService = this.initServices(machineId); + // Setup Auth Handler + const authHandler = appInstantiationService.createInstance(ProxyAuthHandler); + this.toDispose.push(authHandler); - // Setup Auth Handler - const authHandler = appInstantiationService.createInstance(ProxyAuthHandler); - this.toDispose.push(authHandler); + // Open Windows + appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor)); - // Open Windows - appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor)); - - // Post Open Windows Tasks - appInstantiationService.invokeFunction(accessor => this.afterWindowOpen(accessor)); - }); + // Post Open Windows Tasks + appInstantiationService.invokeFunction(accessor => this.afterWindowOpen(accessor)); }); } @@ -319,24 +311,6 @@ export class CodeApplication { }); } - private backupLocalStorage(): TPromise { - const localStorageBackedUp = this.stateService.getItem(CodeApplication.LOCAL_STORAGE_BACKED_UP_KEY); - if (localStorageBackedUp) { - return TPromise.wrap(void 0); - } - - const afterBackupDone = () => { - - // Remember in global storage - this.stateService.setItem(CodeApplication.LOCAL_STORAGE_BACKED_UP_KEY, true); - }; - - const localStorageFile = join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage'); - const localStorageJournalFile = join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage-journal'); - - return copy(localStorageFile, `${localStorageFile}.vscbak`).then(() => copy(localStorageJournalFile, `${localStorageJournalFile}.vscbak`)).then(afterBackupDone, afterBackupDone); - } - private initServices(machineId: string): IInstantiationService { const services = new ServiceCollection(); diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 63ecd4e8768..9eb5162971c 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -151,13 +151,6 @@ function setupIPC(accessor: ServicesAccessor): TPromise { app.dock.show(); } - // Disable the GTK3 emoji picker as it intercepts ctrl+shift+e (and - // doesn't work) - if (platform.isLinux) { - process.env['GTK_IM_MODULE'] = 'gtk-im-context-simple'; - process.env['XMODIFIERS'] = '@im=none'; - } - // Set the VSCODE_PID variable here when we are sure we are the first // instance to startup. Otherwise we would wrongly overwrite the PID process.env['VSCODE_PID'] = String(process.pid); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 81e944f76cb..77378487b62 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -187,6 +187,23 @@ export class CodeWindow implements ICodeWindow { this._win = new BrowserWindow(options); this._id = this._win.id; + // Bug in Electron (https://github.com/electron/electron/issues/10862). On multi-monitor setups, + // it can happen that the position we set to the window is not the correct one on the display. + // To workaround, we ask the window for its position and set it again if not matching. + // This only applies if the window is not fullscreen or maximized and multiple monitors are used. + if (isWindows && !isFullscreenOrMaximized) { + try { + if (screen.getAllDisplays().length > 1) { + const [x, y] = this._win.getPosition(); + if (x !== this.windowState.x || y !== this.windowState.y) { + this._win.setPosition(this.windowState.x, this.windowState.y, false); + } + } + } catch (err) { + this.logService.warn(`Unexpected error fixing window position on windows with multiple windows: ${err}\n${err.stack}`); + } + } + if (useCustomTitleStyle) { this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any } @@ -939,6 +956,11 @@ export class CodeWindow implements ICodeWindow { this.touchBarGroups.push(groupTouchBar); } + // Ugly workaround for native crash on macOS 10.12.1. We are not + // leveraging the API for changing the ESC touch bar item. + // See https://github.com/electron/electron/issues/10442 + (this._win)._setEscapeTouchBarItem = () => { }; + this._win.setTouchBar(new TouchBar({ items: this.touchBarGroups })); } diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index 436f7a96967..942f7f67493 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -174,6 +174,14 @@ class ElementPath { ); } + public static isStrictChildOfViewLines(path: Uint8Array): boolean { + return ( + path.length > 4 + && path[0] === PartFingerprint.OverflowGuard + && path[3] === PartFingerprint.ViewLines + ); + } + public static isChildOfScrollableElement(path: Uint8Array): boolean { return ( path.length >= 2 @@ -621,6 +629,15 @@ export class MouseTargetFactory { } if (domHitTestExecuted) { + // Check if we are hitting a view-line (can happen in the case of inline decorations on empty lines) + // See https://github.com/Microsoft/vscode/issues/46942 + if (ElementPath.isStrictChildOfViewLines(request.targetPath)) { + const lineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset); + if (ctx.model.getLineLength(lineNumber) === 0) { + return request.fulfill(MouseTargetType.CONTENT_EMPTY, new Position(lineNumber, 1), void 0, EMPTY_CONTENT_IN_LINES); + } + } + // We have already executed hit test... return request.fulfill(MouseTargetType.UNKNOWN); } diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index 93934f1131b..0fc4b4ef5ea 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -308,7 +308,8 @@ class Widget { private _layoutBoxInPage(topLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult { let left0 = topLeft.left - ctx.scrollLeft; - if (left0 + width < 0 || left0 > this._contentWidth) { + if (left0 < 0 || left0 > this._contentWidth) { + // Don't render if position is scrolled outside viewport return null; } @@ -390,6 +391,7 @@ class Widget { } if (this.allowEditorOverflow) { + console.log(`here i am: ${JSON.stringify(topLeft)}`); placement = this._layoutBoxInPage(topLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx); } else { placement = this._layoutBoxInViewport(topLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx); diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index deebf469211..35ad7ff531b 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -7,6 +7,7 @@ import 'vs/css!./minimap'; import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart'; +import * as strings from 'vs/base/common/strings'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext'; import { getOrCreateMinimapCharRenderer } from 'vs/editor/common/view/runtimeMinimapCharRenderer'; @@ -897,17 +898,22 @@ export class Minimap extends ViewPart { // No need to render anything since space is invisible dx += charWidth; } else { - if (renderMinimap === RenderMinimap.Large) { - minimapCharRenderer.x2RenderChar(target, dx, dy, charCode, tokenColor, backgroundColor, useLighterFont); - } else if (renderMinimap === RenderMinimap.Small) { - minimapCharRenderer.x1RenderChar(target, dx, dy, charCode, tokenColor, backgroundColor, useLighterFont); - } else if (renderMinimap === RenderMinimap.LargeBlocks) { - minimapCharRenderer.x2BlockRenderChar(target, dx, dy, tokenColor, backgroundColor, useLighterFont); - } else { - // RenderMinimap.SmallBlocks - minimapCharRenderer.x1BlockRenderChar(target, dx, dy, tokenColor, backgroundColor, useLighterFont); + // Render twice for a full width character + let count = strings.isFullWidthCharacter(charCode) ? 2 : 1; + + for (let i = 0; i < count; i++) { + if (renderMinimap === RenderMinimap.Large) { + minimapCharRenderer.x2RenderChar(target, dx, dy, charCode, tokenColor, backgroundColor, useLighterFont); + } else if (renderMinimap === RenderMinimap.Small) { + minimapCharRenderer.x1RenderChar(target, dx, dy, charCode, tokenColor, backgroundColor, useLighterFont); + } else if (renderMinimap === RenderMinimap.LargeBlocks) { + minimapCharRenderer.x2BlockRenderChar(target, dx, dy, tokenColor, backgroundColor, useLighterFont); + } else { + // RenderMinimap.SmallBlocks + minimapCharRenderer.x1BlockRenderChar(target, dx, dy, tokenColor, backgroundColor, useLighterFont); + } + dx += charWidth; } - dx += charWidth; } } } diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 57c4239f480..3c463fe6c46 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -370,6 +370,11 @@ const editorConfiguration: IConfigurationNode = { ] }, "The modifier to be used to add multiple cursors with the mouse. `ctrlCmd` maps to `Control` on Windows and Linux and to `Command` on macOS. The Go To Definition and Open Link mouse gestures will adapt such that they do not conflict with the multicursor modifier.") }, + 'editor.multiCursorMergeOverlapping': { + 'type': 'boolean', + 'default': EDITOR_DEFAULTS.multiCursorMergeOverlapping, + 'description': nls.localize('multiCursorMergeOverlapping', "Merge multiple cursors when they are overlapping.") + }, 'editor.quickSuggestions': { 'anyOf': [ { @@ -663,6 +668,16 @@ const editorConfiguration: IConfigurationNode = { 'default': true, 'description': nls.localize('ignoreTrimWhitespace', "Controls if the diff editor shows changes in leading or trailing whitespace as diffs") }, + 'editor.largeFileSize': { + 'type': 'number', + 'default': EDITOR_MODEL_DEFAULTS.largeFileSize, + 'description': nls.localize('largeFileSize', "Controls file size threshold in bytes beyond which special optimization rules are applied") + }, + 'editor.largeFileLineCount': { + 'type': 'number', + 'default': EDITOR_MODEL_DEFAULTS.largeFileLineCount, + 'description': nls.localize('largeFileLineCount', "Controls file size threshold in terms of line count beyond which special optimization rules are applied") + }, 'diffEditor.renderIndicators': { 'type': 'boolean', 'default': true, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 2dac3a5df9e..48d76961005 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -381,6 +381,11 @@ export interface IEditorOptions { * Defaults to 'alt' */ multiCursorModifier?: 'ctrlCmd' | 'alt'; + /** + * Merge overlapping selections. + * Defaults to true + */ + multiCursorMergeOverlapping?: boolean; /** * Configure the editor's accessibility support. * Defaults to 'auto'. It is best to leave this to 'auto'. @@ -878,6 +883,7 @@ export interface IValidatedEditorOptions { readonly emptySelectionClipboard: boolean; readonly useTabStops: boolean; readonly multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; + readonly multiCursorMergeOverlapping: boolean; readonly accessibilitySupport: 'auto' | 'off' | 'on'; readonly viewInfo: InternalEditorViewOptions; @@ -900,6 +906,7 @@ export class InternalEditorOptions { */ readonly accessibilitySupport: platform.AccessibilitySupport; readonly multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; + readonly multiCursorMergeOverlapping: boolean; // ---- cursor options readonly wordSeparators: string; @@ -928,6 +935,7 @@ export class InternalEditorOptions { readOnly: boolean; accessibilitySupport: platform.AccessibilitySupport; multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; + multiCursorMergeOverlapping: boolean; wordSeparators: string; autoClosingBrackets: boolean; autoIndent: boolean; @@ -948,6 +956,7 @@ export class InternalEditorOptions { this.readOnly = source.readOnly; this.accessibilitySupport = source.accessibilitySupport; this.multiCursorModifier = source.multiCursorModifier; + this.multiCursorMergeOverlapping = source.multiCursorMergeOverlapping; this.wordSeparators = source.wordSeparators; this.autoClosingBrackets = source.autoClosingBrackets; this.autoIndent = source.autoIndent; @@ -974,6 +983,7 @@ export class InternalEditorOptions { && this.readOnly === other.readOnly && this.accessibilitySupport === other.accessibilitySupport && this.multiCursorModifier === other.multiCursorModifier + && this.multiCursorMergeOverlapping === other.multiCursorMergeOverlapping && this.wordSeparators === other.wordSeparators && this.autoClosingBrackets === other.autoClosingBrackets && this.autoIndent === other.autoIndent @@ -1001,6 +1011,7 @@ export class InternalEditorOptions { readOnly: (this.readOnly !== newOpts.readOnly), accessibilitySupport: (this.accessibilitySupport !== newOpts.accessibilitySupport), multiCursorModifier: (this.multiCursorModifier !== newOpts.multiCursorModifier), + multiCursorMergeOverlapping: (this.multiCursorMergeOverlapping !== newOpts.multiCursorMergeOverlapping), wordSeparators: (this.wordSeparators !== newOpts.wordSeparators), autoClosingBrackets: (this.autoClosingBrackets !== newOpts.autoClosingBrackets), autoIndent: (this.autoIndent !== newOpts.autoIndent), @@ -1354,6 +1365,7 @@ export interface IConfigurationChangedEvent { readonly readOnly: boolean; readonly accessibilitySupport: boolean; readonly multiCursorModifier: boolean; + readonly multiCursorMergeOverlapping: boolean; readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; readonly autoIndent: boolean; @@ -1539,6 +1551,7 @@ export class EditorOptionsValidator { emptySelectionClipboard: _boolean(opts.emptySelectionClipboard, defaults.emptySelectionClipboard), useTabStops: _boolean(opts.useTabStops, defaults.useTabStops), multiCursorModifier: multiCursorModifier, + multiCursorMergeOverlapping: _boolean(opts.multiCursorMergeOverlapping, defaults.multiCursorMergeOverlapping), accessibilitySupport: _stringSet<'auto' | 'on' | 'off'>(opts.accessibilitySupport, defaults.accessibilitySupport, ['auto', 'on', 'off']), viewInfo: viewInfo, contribInfo: contribInfo, @@ -1774,6 +1787,7 @@ export class InternalEditorOptionsFactory { emptySelectionClipboard: opts.emptySelectionClipboard, useTabStops: opts.useTabStops, multiCursorModifier: opts.multiCursorModifier, + multiCursorMergeOverlapping: opts.multiCursorMergeOverlapping, accessibilitySupport: opts.accessibilitySupport, viewInfo: { @@ -1981,6 +1995,7 @@ export class InternalEditorOptionsFactory { readOnly: opts.readOnly, accessibilitySupport: accessibilitySupport, multiCursorModifier: opts.multiCursorModifier, + multiCursorMergeOverlapping: opts.multiCursorMergeOverlapping, wordSeparators: opts.wordSeparators, autoClosingBrackets: opts.autoClosingBrackets, autoIndent: opts.autoIndent, @@ -2189,7 +2204,9 @@ export const EDITOR_MODEL_DEFAULTS = { tabSize: 4, insertSpaces: true, detectIndentation: true, - trimAutoWhitespace: true + trimAutoWhitespace: true, + largeFileSize: 20 * 1024 * 1024, // 20 MB + largeFileLineCount: 300 * 1000 // 300K lines }; /** @@ -2217,6 +2234,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { emptySelectionClipboard: true, useTabStops: true, multiCursorModifier: 'altKey', + multiCursorMergeOverlapping: true, accessibilitySupport: 'auto', viewInfo: { diff --git a/src/vs/editor/common/controller/cursorCollection.ts b/src/vs/editor/common/controller/cursorCollection.ts index 9fcae512f2f..c50e7d3e4e6 100644 --- a/src/vs/editor/common/controller/cursorCollection.ts +++ b/src/vs/editor/common/controller/cursorCollection.ts @@ -193,6 +193,10 @@ export class CursorCollection { const currentViewSelection = current.viewSelection; const nextViewSelection = next.viewSelection; + if (!this.context.config.multiCursorMergeOverlapping) { + continue; + } + let shouldMergeCursors: boolean; if (nextViewSelection.isEmpty() || currentViewSelection.isEmpty()) { // Merge touching cursors if one of them is collapsed diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 8c6c99f2d0c..8f0ff9075d2 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -78,6 +78,7 @@ export class CursorConfiguration { public readonly useTabStops: boolean; public readonly wordSeparators: string; public readonly emptySelectionClipboard: boolean; + public readonly multiCursorMergeOverlapping: boolean; public readonly autoClosingBrackets: boolean; public readonly autoIndent: boolean; public readonly autoClosingPairsOpen: CharacterMap; @@ -92,6 +93,7 @@ export class CursorConfiguration { e.layoutInfo || e.wordSeparators || e.emptySelectionClipboard + || e.multiCursorMergeOverlapping || e.autoClosingBrackets || e.useTabStops || e.lineHeight @@ -118,6 +120,7 @@ export class CursorConfiguration { this.useTabStops = c.useTabStops; this.wordSeparators = c.wordSeparators; this.emptySelectionClipboard = c.emptySelectionClipboard; + this.multiCursorMergeOverlapping = c.multiCursorMergeOverlapping; this.autoClosingBrackets = c.autoClosingBrackets; this.autoIndent = c.autoIndent; diff --git a/src/vs/editor/common/controller/cursorWordOperations.ts b/src/vs/editor/common/controller/cursorWordOperations.ts index 8f83c1f8621..24bbcac19c3 100644 --- a/src/vs/editor/common/controller/cursorWordOperations.ts +++ b/src/vs/editor/common/controller/cursorWordOperations.ts @@ -24,6 +24,10 @@ interface IFindWordResult { * The word type. */ wordType: WordType; + /** + * The reason the word ended. + */ + nextCharClass: WordCharacterClass; } const enum WordType { @@ -39,9 +43,9 @@ export const enum WordNavigationType { export class WordOperations { - private static _createWord(lineContent: string, wordType: WordType, start: number, end: number): IFindWordResult { + private static _createWord(lineContent: string, wordType: WordType, nextCharClass: WordCharacterClass, start: number, end: number): IFindWordResult { // console.log('WORD ==> ' + start + ' => ' + end + ':::: <<<' + lineContent.substring(start, end) + '>>>'); - return { start: start, end: end, wordType: wordType }; + return { start: start, end: end, wordType: wordType, nextCharClass: nextCharClass }; } private static _findPreviousWordOnLine(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position): IFindWordResult { @@ -57,23 +61,23 @@ export class WordOperations { if (chClass === WordCharacterClass.Regular) { if (wordType === WordType.Separator) { - return this._createWord(lineContent, wordType, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); + return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); } wordType = WordType.Regular; } else if (chClass === WordCharacterClass.WordSeparator) { if (wordType === WordType.Regular) { - return this._createWord(lineContent, wordType, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); + return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); } wordType = WordType.Separator; } else if (chClass === WordCharacterClass.Whitespace) { if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); + return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); } } } if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, 0, this._findEndOfWord(lineContent, wordSeparators, wordType, 0)); + return this._createWord(lineContent, wordType, WordCharacterClass.Whitespace, 0, this._findEndOfWord(lineContent, wordSeparators, wordType, 0)); } return null; @@ -113,23 +117,23 @@ export class WordOperations { if (chClass === WordCharacterClass.Regular) { if (wordType === WordType.Separator) { - return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); + return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); } wordType = WordType.Regular; } else if (chClass === WordCharacterClass.WordSeparator) { if (wordType === WordType.Regular) { - return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); + return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); } wordType = WordType.Separator; } else if (chClass === WordCharacterClass.Whitespace) { if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); + return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); } } } if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, len - 1), len); + return this._createWord(lineContent, wordType, WordCharacterClass.Whitespace, this._findStartOfWord(lineContent, wordSeparators, wordType, len - 1), len); } return null; @@ -200,6 +204,12 @@ export class WordOperations { let nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, column)); if (wordNavigationType === WordNavigationType.WordEnd) { + if (nextWordOnLine && nextWordOnLine.wordType === WordType.Separator) { + if (nextWordOnLine.end - nextWordOnLine.start === 1 && nextWordOnLine.nextCharClass === WordCharacterClass.Regular) { + // Skip over a word made up of one single separator and followed by a regular character + nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1)); + } + } if (nextWordOnLine) { column = nextWordOnLine.end + 1; } else { diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index ff909869d8e..703a8edb897 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -396,6 +396,8 @@ export interface ITextModelCreationOptions { trimAutoWhitespace: boolean; defaultEOL: DefaultEndOfLine; isForSimpleWidget: boolean; + largeFileSize: number; + largeFileLineCount: number; } export interface ITextModelUpdateOptions { @@ -566,6 +568,10 @@ export interface ITextModel { */ getLineContent(lineNumber: number): string; + /** + * Get the text length for a certain line. + */ + getLineLength(lineNumber: number): number; /** * Get the text for all lines. diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 3975b563698..8a32b369276 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -155,8 +155,6 @@ class TextModelSnapshot implements ITextSnapshot { export class TextModel extends Disposable implements model.ITextModel { private static readonly MODEL_SYNC_LIMIT = 50 * 1024 * 1024; // 50 MB - private static readonly MODEL_TOKENIZATION_LIMIT = 20 * 1024 * 1024; // 20 MB - private static readonly MANY_MANY_LINES = 300 * 1000; // 300K lines public static DEFAULT_CREATION_OPTIONS: model.ITextModelCreationOptions = { isForSimpleWidget: false, @@ -165,6 +163,8 @@ export class TextModel extends Disposable implements model.ITextModel { detectIndentation: false, defaultEOL: model.DefaultEndOfLine.LF, trimAutoWhitespace: EDITOR_MODEL_DEFAULTS.trimAutoWhitespace, + largeFileSize: EDITOR_MODEL_DEFAULTS.largeFileSize, + largeFileLineCount: EDITOR_MODEL_DEFAULTS.largeFileLineCount, }; public static createFromString(text: string, options: model.ITextModelCreationOptions = TextModel.DEFAULT_CREATION_OPTIONS, languageIdentifier: LanguageIdentifier = null, uri: URI = null): TextModel { @@ -289,8 +289,8 @@ export class TextModel extends Disposable implements model.ITextModel { // If a model is too large at construction time, it will never get tokenized, // under no circumstances. this._isTooLargeForTokenization = ( - (bufferTextLength > TextModel.MODEL_TOKENIZATION_LIMIT) - || (bufferLineCount > TextModel.MANY_MANY_LINES) + (bufferTextLength > creationOptions.largeFileSize) + || (bufferLineCount > creationOptions.largeFileLineCount) ); this._shouldSimplifyMode = ( @@ -772,6 +772,15 @@ export class TextModel extends Disposable implements model.ITextModel { return this._buffer.getLineContent(lineNumber); } + public getLineLength(lineNumber: number): number { + this._assertNotDisposed(); + if (lineNumber < 1 || lineNumber > this.getLineCount()) { + throw new Error('Illegal value for lineNumber'); + } + + return this._buffer.getLineLength(lineNumber); + } + public getLinesContent(): string[] { this._assertNotDisposed(); return this._buffer.getLinesContent(); diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index fa395f924f0..b189ac8390c 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -197,6 +197,8 @@ interface IRawConfig { insertSpaces?: any; detectIndentation?: any; trimAutoWhitespace?: any; + largeFileSize?: any; + largeFileLineCount?: any; }; } @@ -275,13 +277,31 @@ export class ModelServiceImpl implements IModelService { detectIndentation = (config.editor.detectIndentation === 'false' ? false : Boolean(config.editor.detectIndentation)); } + let largeFileSize = EDITOR_MODEL_DEFAULTS.largeFileSize; + if (config.editor && typeof config.editor.largeFileSize !== 'undefined') { + let parsedlargeFileSize = parseInt(config.editor.largeFileSize, 10); + if (!isNaN(parsedlargeFileSize)) { + largeFileSize = parsedlargeFileSize; + } + } + + let largeFileLineCount = EDITOR_MODEL_DEFAULTS.largeFileLineCount; + if (config.editor && typeof config.editor.largeFileLineCount !== 'undefined') { + let parsedlargeFileLineCount = parseInt(config.editor.largeFileLineCount, 10); + if (!isNaN(parsedlargeFileLineCount)) { + largeFileLineCount = parsedlargeFileLineCount; + } + } + return { isForSimpleWidget: isForSimpleWidget, tabSize: tabSize, insertSpaces: insertSpaces, detectIndentation: detectIndentation, defaultEOL: newDefaultEOL, - trimAutoWhitespace: trimAutoWhitespace + trimAutoWhitespace: trimAutoWhitespace, + largeFileSize: largeFileSize, + largeFileLineCount: largeFileLineCount }; } diff --git a/src/vs/editor/common/viewModel/splitLinesCollection.ts b/src/vs/editor/common/viewModel/splitLinesCollection.ts index 3141915e9df..b80a077c786 100644 --- a/src/vs/editor/common/viewModel/splitLinesCollection.ts +++ b/src/vs/editor/common/viewModel/splitLinesCollection.ts @@ -41,6 +41,7 @@ export interface ILineMapperFactory { export interface ISimpleModel { getLineTokens(lineNumber: number): LineTokens; getLineContent(lineNumber: number): string; + getLineLength(lineNumber: number): number; getLineMinColumn(lineNumber: number): number; getLineMaxColumn(lineNumber: number): number; getValueInRange(range: IRange, eol?: EndOfLinePreference): string; @@ -52,6 +53,7 @@ export interface ISplitLine { getViewLineCount(): number; getViewLineContent(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): string; + getViewLineLength(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number; getViewLineMinColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number; getViewLineMaxColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number; getViewLineData(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): ViewLineData; @@ -82,6 +84,7 @@ export interface IViewModelLinesCollection { warmUpLookupCache(viewStartLineNumber: number, viewEndLineNumber: number): void; getViewLinesIndentGuides(viewStartLineNumber: number, viewEndLineNumber: number): number[]; getViewLineContent(viewLineNumber: number): string; + getViewLineLength(viewLineNumber: number): number; getViewLineMinColumn(viewLineNumber: number): number; getViewLineMaxColumn(viewLineNumber: number): number; getViewLineData(viewLineNumber: number): ViewLineData; @@ -570,6 +573,16 @@ export class SplitLinesCollection implements IViewModelLinesCollection { return this.lines[lineIndex].getViewLineContent(this.model, lineIndex + 1, remainder); } + public getViewLineLength(viewLineNumber: number): number { + this._ensureValidState(); + viewLineNumber = this._toValidViewLineNumber(viewLineNumber); + let r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1); + let lineIndex = r.index; + let remainder = r.remainder; + + return this.lines[lineIndex].getViewLineLength(this.model, lineIndex + 1, remainder); + } + public getViewLineMinColumn(viewLineNumber: number): number { this._ensureValidState(); viewLineNumber = this._toValidViewLineNumber(viewLineNumber); @@ -815,6 +828,10 @@ class VisibleIdentitySplitLine implements ISplitLine { return model.getLineContent(modelLineNumber); } + public getViewLineLength(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number { + return model.getLineLength(modelLineNumber); + } + public getViewLineMinColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number { return model.getLineMinColumn(modelLineNumber); } @@ -880,6 +897,10 @@ class InvisibleIdentitySplitLine implements ISplitLine { throw new Error('Not supported'); } + public getViewLineLength(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number { + throw new Error('Not supported'); + } + public getViewLineMinColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number { throw new Error('Not supported'); } @@ -973,6 +994,21 @@ export class SplitLine implements ISplitLine { return r; } + public getViewLineLength(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number { + if (!this._isVisible) { + throw new Error('Not supported'); + } + let startOffset = this.getInputStartOffsetOfOutputLineIndex(outputLineIndex); + let endOffset = this.getInputEndOffsetOfOutputLineIndex(model, modelLineNumber, outputLineIndex); + let r = endOffset - startOffset; + + if (outputLineIndex > 0) { + r = this.wrappedIndent.length + r; + } + + return r; + } + public getViewLineMinColumn(model: ITextModel, modelLineNumber: number, outputLineIndex: number): number { if (!this._isVisible) { throw new Error('Not supported'); @@ -1218,6 +1254,10 @@ export class IdentityLinesCollection implements IViewModelLinesCollection { return this.model.getLineContent(viewLineNumber); } + public getViewLineLength(viewLineNumber: number): number { + return this.model.getLineLength(viewLineNumber); + } + public getViewLineMinColumn(viewLineNumber: number): number { return this.model.getLineMinColumn(viewLineNumber); } diff --git a/src/vs/editor/common/viewModel/viewModel.ts b/src/vs/editor/common/viewModel/viewModel.ts index 1702d8fd59f..1ade6a4fd4a 100644 --- a/src/vs/editor/common/viewModel/viewModel.ts +++ b/src/vs/editor/common/viewModel/viewModel.ts @@ -131,6 +131,7 @@ export interface IViewModel { getTabSize(): number; getLineCount(): number; getLineContent(lineNumber: number): string; + getLineLength(lineNumber: number): number; getLinesIndentGuides(startLineNumber: number, endLineNumber: number): number[]; getLineMinColumn(lineNumber: number): number; getLineMaxColumn(lineNumber: number): number; diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index e857d492b4c..fa9273c3f0b 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -474,6 +474,10 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel return this.lines.getViewLineContent(lineNumber); } + public getLineLength(lineNumber: number): number { + return this.lines.getViewLineLength(lineNumber); + } + public getLineMinColumn(lineNumber: number): number { return this.lines.getViewLineMinColumn(lineNumber); } diff --git a/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts b/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts index 6c3284eb35b..d7ed7bcbf60 100644 --- a/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts +++ b/src/vs/editor/contrib/linesOperations/test/linesOperations.test.ts @@ -8,12 +8,12 @@ import * as assert from 'assert'; import { Selection } from 'vs/editor/common/core/selection'; import { Position } from 'vs/editor/common/core/position'; import { Handler } from 'vs/editor/common/editorCommon'; -import { ITextModel, DefaultEndOfLine } from 'vs/editor/common/model'; +import { ITextModel } from 'vs/editor/common/model'; import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { DeleteAllLeftAction, JoinLinesAction, TransposeAction, UpperCaseAction, LowerCaseAction, DeleteAllRightAction, InsertLineBeforeAction, InsertLineAfterAction, IndentLinesAction, SortLinesAscendingAction, SortLinesDescendingAction } from 'vs/editor/contrib/linesOperations/linesOperations'; import { Cursor } from 'vs/editor/common/controller/cursor'; -import { TextModel } from 'vs/editor/common/model/textModel'; import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands'; +import { createTextModel } from 'vs/editor/test/common/editorTestUtils'; suite('Editor Contrib - Line Operations', () => { suite('SortLinesAscendingAction', () => { @@ -746,17 +746,12 @@ suite('Editor Contrib - Line Operations', () => { test('Bug 18276:[editor] Indentation broken when selection is empty', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'function baz() {' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true } ); diff --git a/src/vs/editor/contrib/quickFix/quickFixCommands.ts b/src/vs/editor/contrib/quickFix/quickFixCommands.ts index 8f499e12d57..9d1a7db3a8a 100644 --- a/src/vs/editor/contrib/quickFix/quickFixCommands.ts +++ b/src/vs/editor/contrib/quickFix/quickFixCommands.ts @@ -26,6 +26,7 @@ import { CodeAction } from 'vs/editor/common/modes'; import { BulkEdit } from 'vs/editor/browser/services/bulkEdit'; import { IFileService } from 'vs/platform/files/common/files'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; +import { MessageController } from 'vs/editor/contrib/message/messageController'; export class QuickFixController implements IEditorContribution { @@ -108,12 +109,8 @@ export class QuickFixController implements IEditorContribution { this._quickFixContextMenu.show(this._lightBulbWidget.model.fixes, coords); } - public triggerFromEditorSelection(): void { - this._model.trigger({ type: 'manual' }); - } - - public triggerCodeActionFromEditorSelection(kind?: CodeActionKind, autoApply?: CodeActionAutoApply): void { - this._model.trigger({ type: 'manual', kind, autoApply }); + public triggerFromEditorSelection(kind?: CodeActionKind, autoApply?: CodeActionAutoApply): TPromise { + return this._model.trigger({ type: 'manual', kind, autoApply }); } private _updateLightBulbTitle(): void { @@ -138,6 +135,25 @@ export class QuickFixController implements IEditorContribution { } } +function showCodeActionsForEditorSelection( + editor: ICodeEditor, + notAvailableMessage: string, + kind?: CodeActionKind, + autoApply?: CodeActionAutoApply +) { + const controller = QuickFixController.get(editor); + if (!controller) { + return; + } + + const pos = editor.getPosition(); + controller.triggerFromEditorSelection(kind, autoApply).then(codeActions => { + if (!codeActions || !codeActions.length) { + MessageController.get(editor).showMessage(notAvailableMessage, pos); + } + }); +} + export class QuickFixAction extends EditorAction { static readonly Id = 'editor.action.quickFix'; @@ -156,10 +172,7 @@ export class QuickFixAction extends EditorAction { } public run(accessor: ServicesAccessor, editor: ICodeEditor): void { - let controller = QuickFixController.get(editor); - if (controller) { - controller.triggerFromEditorSelection(); - } + return showCodeActionsForEditorSelection(editor, nls.localize('editor.action.quickFix.noneMessage', "No code actions available")); } } @@ -212,11 +225,8 @@ export class CodeActionCommand extends EditorCommand { } public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, userArg: any) { - const controller = QuickFixController.get(editor); - if (controller) { - const args = CodeActionCommandArgs.fromUser(userArg); - controller.triggerCodeActionFromEditorSelection(args.kind, args.apply); - } + const args = CodeActionCommandArgs.fromUser(userArg); + return showCodeActionsForEditorSelection(editor, nls.localize('editor.action.quickFix.noneMessage', "No code actions available"), args.kind, args.apply); } } @@ -234,15 +244,19 @@ export class RefactorAction extends EditorAction { kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_R + }, + menuOpts: { + group: '1_modification', + order: 2 } }); } public run(accessor: ServicesAccessor, editor: ICodeEditor): void { - const controller = QuickFixController.get(editor); - if (controller) { - controller.triggerCodeActionFromEditorSelection(CodeActionKind.Refactor, CodeActionAutoApply.Never); - } + return showCodeActionsForEditorSelection(editor, + nls.localize('editor.action.refactor.noneMessage', "No refactorings available"), + CodeActionKind.Refactor, + CodeActionAutoApply.Never); } } diff --git a/src/vs/editor/contrib/quickFix/quickFixModel.ts b/src/vs/editor/contrib/quickFix/quickFixModel.ts index 899b1d93da5..0d08f4d4a8e 100644 --- a/src/vs/editor/contrib/quickFix/quickFixModel.ts +++ b/src/vs/editor/contrib/quickFix/quickFixModel.ts @@ -37,12 +37,12 @@ export class QuickFixOracle { this._disposables = dispose(this._disposables); } - trigger(trigger: CodeActionTrigger): void { + trigger(trigger: CodeActionTrigger) { let rangeOrSelection = this._getRangeOfMarker() || this._getRangeOfSelectionUnlessWhitespaceEnclosed(); if (!rangeOrSelection && trigger.type === 'manual') { rangeOrSelection = this._editor.getSelection(); } - this._createEventAndSignalChange(trigger, rangeOrSelection); + return this._createEventAndSignalChange(trigger, rangeOrSelection); } private _onMarkerChanges(resources: URI[]): void { @@ -99,7 +99,7 @@ export class QuickFixOracle { return selection; } - private _createEventAndSignalChange(trigger: CodeActionTrigger, rangeOrSelection: Range | Selection): void { + private _createEventAndSignalChange(trigger: CodeActionTrigger, rangeOrSelection: Range | Selection): TPromise { if (!rangeOrSelection) { // cancel this._signalChange({ @@ -108,6 +108,7 @@ export class QuickFixOracle { position: undefined, fixes: undefined, }); + return TPromise.as(undefined); } else { // actual const model = this._editor.getModel(); @@ -121,6 +122,7 @@ export class QuickFixOracle { position, fixes }); + return fixes; } } } @@ -177,9 +179,10 @@ export class QuickFixModel { } } - trigger(trigger: CodeActionTrigger): void { + trigger(trigger: CodeActionTrigger): TPromise { if (this._quickFixOracle) { - this._quickFixOracle.trigger(trigger); + return this._quickFixOracle.trigger(trigger); } + return TPromise.as(undefined); } } diff --git a/src/vs/editor/contrib/wordOperations/test/wordOperations.test.ts b/src/vs/editor/contrib/wordOperations/test/wordOperations.test.ts index aaea8d65c8c..c643d6efda2 100644 --- a/src/vs/editor/contrib/wordOperations/test/wordOperations.test.ts +++ b/src/vs/editor/contrib/wordOperations/test/wordOperations.test.ts @@ -267,9 +267,7 @@ suite('WordOperations', () => { moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a'.length + 1, '007'); moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+='.length + 1, '008'); moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3'.length + 1, '009'); - moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +'.length + 1, '010'); moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5'.length + 1, '011'); - moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-'.length + 1, '012'); moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-3'.length + 1, '013'); moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-3 +'.length + 1, '014'); moveWordRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-3 + 7'.length + 1, '015'); @@ -279,6 +277,19 @@ suite('WordOperations', () => { }); }); + test('issue #41199: moveWordRight', () => { + withTestCodeEditor([ + 'console.log(err)' + ], {}, (editor, _) => { + editor.setPosition(new Position(1, 1)); + + moveWordRight(editor); assert.equal(editor.getPosition().column, 'console'.length + 1, '001'); + moveWordRight(editor); assert.equal(editor.getPosition().column, 'console.log'.length + 1, '002'); + moveWordRight(editor); assert.equal(editor.getPosition().column, 'console.log(err'.length + 1, '003'); + moveWordRight(editor); assert.equal(editor.getPosition().column, 'console.log(err)'.length + 1, '004'); + }); + }); + test('moveWordEndRight', () => { withTestCodeEditor([ ' /* Just some more text a+= 3 +5-3 + 7 */ ' @@ -293,9 +304,7 @@ suite('WordOperations', () => { moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a'.length + 1, '007'); moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+='.length + 1, '008'); moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3'.length + 1, '009'); - moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +'.length + 1, '010'); moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5'.length + 1, '011'); - moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-'.length + 1, '012'); moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-3'.length + 1, '013'); moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-3 +'.length + 1, '014'); moveWordEndRight(editor); assert.equal(editor.getPosition().column, ' /* Just some more text a+= 3 +5-3 + 7'.length + 1, '015'); diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index f6562068e8a..7e23594cca4 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -11,7 +11,7 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { Handler, ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon'; -import { EndOfLinePreference, DefaultEndOfLine, ITextModelCreationOptions, ITextModel, EndOfLineSequence } from 'vs/editor/common/model'; +import { EndOfLinePreference, ITextModel, EndOfLineSequence } from 'vs/editor/common/model'; import { TextModel } from 'vs/editor/common/model/textModel'; import { IndentAction, IndentationRule } from 'vs/editor/common/modes/languageConfiguration'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; @@ -24,8 +24,9 @@ import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { ViewModel } from 'vs/editor/common/viewModel/viewModelImpl'; import { NULL_STATE } from 'vs/editor/common/modes/nullMode'; import { TokenizationResult2 } from 'vs/editor/common/core/token'; +import { createTextModel, IRelaxedTextModelCreationOptions } from 'vs/editor/test/common/editorTestUtils'; -let H = Handler; +const H = Handler; // --------- utils @@ -149,7 +150,7 @@ suite('Editor Controller - Cursor', () => { LINE4 + '\r\n' + LINE5; - thisModel = TextModel.createFromString(text); + thisModel = createTextModel(text); thisConfiguration = new TestConfiguration(null); thisViewModel = new ViewModel(0, thisConfiguration, thisModel, null); @@ -725,7 +726,7 @@ suite('Editor Controller - Cursor', () => { }); test('issue #4905 - column select is biased to the right', () => { - const model = TextModel.createFromString([ + const model = createTextModel([ 'var gulp = require("gulp");', 'var path = require("path");', 'var rimraf = require("rimraf");', @@ -761,7 +762,7 @@ suite('Editor Controller - Cursor', () => { }); test('issue #20087: column select with mouse', () => { - const model = TextModel.createFromString([ + const model = createTextModel([ '', '', '', @@ -823,7 +824,7 @@ suite('Editor Controller - Cursor', () => { }); test('issue #20087: column select with keyboard', () => { - const model = TextModel.createFromString([ + const model = createTextModel([ '', '', '', @@ -875,7 +876,7 @@ suite('Editor Controller - Cursor', () => { }); test('column select with keyboard', () => { - const model = TextModel.createFromString([ + const model = createTextModel([ 'var gulp = require("gulp");', 'var path = require("path");', 'var rimraf = require("rimraf");', @@ -1131,18 +1132,13 @@ class IndentRulesMode extends MockMode { suite('Editor Controller - Regression tests', () => { test('issue Microsoft/monaco-editor#443: Indentation of a single row deletes selected text in some cases', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'Hello world!', 'another line' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, - insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: false + insertSpaces: false }, ); @@ -1158,16 +1154,12 @@ suite('Editor Controller - Regression tests', () => { }); test('Bug 9121: Auto indent + undo + redo is funky', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ '' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, trimAutoWhitespace: false }, ); @@ -1223,7 +1215,7 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #46208: Allow empty selections in the undo/redo stack', () => { - let model = TextModel.createFromString(''); + let model = createTextModel(''); withTestCodeEditor(null, { model: model }, (editor, cursor) => { cursorCommand(cursor, H.Type, { text: 'Hello' }, 'keyboard'); @@ -1282,18 +1274,11 @@ suite('Editor Controller - Regression tests', () => { test('bug #16815:Shift+Tab doesn\'t go back to tabstop', () => { let mode = new OnEnterMode(IndentAction.IndentOutdent); - let model = TextModel.createFromString( + let model = createTextModel( [ ' function baz() {' ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - }, + undefined, mode.getLanguageIdentifier() ); @@ -1311,18 +1296,10 @@ suite('Editor Controller - Regression tests', () => { }); test('Bug #18293:[regression][editor] Can\'t outdent whitespace line', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ ' ' - ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { model: model }, (editor, cursor) => { @@ -1338,7 +1315,7 @@ suite('Editor Controller - Regression tests', () => { }); test('Bug #16657: [editor] Tab on empty line of zero indentation moves cursor to position (1,1)', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'function baz() {', '\tfunction hello() { // something here', @@ -1349,12 +1326,7 @@ suite('Editor Controller - Regression tests', () => { '' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, ); @@ -1414,8 +1386,7 @@ suite('Editor Controller - Regression tests', () => { text: [ 'hello' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, tabSize: 4, insertSpaces: true, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 1, 3, false); moveTo(cursor, 1, 5, true); @@ -1432,20 +1403,12 @@ suite('Editor Controller - Regression tests', () => { test('issue #1140: Backspace stops prematurely', () => { let mode = new SurroundingMode(); - let model = TextModel.createFromString( + let model = createTextModel( [ 'function baz() {', ' return 1;', '};' - ].join('\n'), - { - isForSimpleWidget: false, - tabSize: 4, - insertSpaces: true, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - }, + ].join('\n') ); withTestCodeEditor(null, { model: model }, (editor, cursor) => { @@ -1602,20 +1565,12 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #3071: Investigate why undo stack gets corrupted', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'some lines', 'and more lines', 'just some text', - ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { model: model }, (editor, cursor) => { @@ -1667,8 +1622,7 @@ suite('Editor Controller - Regression tests', () => { 'and more lines', 'just some text', ], - languageIdentifier: null, - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: null }, (model, cursor) => { moveTo(cursor, 3, 1, false); @@ -1683,22 +1637,14 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #3463: pressing tab adds spaces, but not as many as for a tab', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'function a() {', '\tvar a = {', '\t\tx: 3', '\t};', '}', - ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { model: model }, (editor, cursor) => { @@ -1711,18 +1657,13 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #4312: trying to type a tab character over a sequence of spaces results in unexpected behaviour', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'var foo = 123; // this is a comment', 'var bar = 4; // another comment' ].join('\n'), { - isForSimpleWidget: false, insertSpaces: false, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true } ); @@ -1816,7 +1757,7 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #33788: Wrong cursor position when double click to select a word', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'Just some text' ].join('\n') @@ -1972,7 +1913,7 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #41573 - delete across multiple lines does not shrink the selection when word wraps', () => { - const model = TextModel.createFromString([ + const model = createTextModel([ 'Authorization: \'Bearer pHKRfCTFSnGxs6akKlb9ddIXcca0sIUSZJutPHYqz7vEeHdMTMh0SGN0IGU3a0n59DXjTLRsj5EJ2u33qLNIFi9fk5XF8pK39PndLYUZhPt4QvHGLScgSkK0L4gwzkzMloTQPpKhqiikiIOvyNNSpd2o8j29NnOmdTUOKi9DVt74PD2ohKxyOrWZ6oZprTkb3eKajcpnS0LABKfaw2rmv4\',' ].join('\n')); const config = new TestConfiguration({ @@ -2024,18 +1965,10 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #44805: Should not be able to undo in readonly editor', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ '' - ].join('\n'), - { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, - insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { readOnly: true, model: model }, (editor, cursor) => { @@ -2064,7 +1997,7 @@ suite('Editor Controller - Regression tests', () => { const LANGUAGE_ID = 'modelModeTest1'; const languageRegistration = TokenizationRegistry.register(LANGUAGE_ID, tokenizationSupport); - let model = TextModel.createFromString('Just text', undefined, new LanguageIdentifier(LANGUAGE_ID, 0)); + let model = createTextModel('Just text', undefined, new LanguageIdentifier(LANGUAGE_ID, 0)); withTestCodeEditor(null, { model: model }, (editor1, cursor1) => { withTestCodeEditor(null, { model: model }, (editor2, cursor2) => { @@ -2080,6 +2013,40 @@ suite('Editor Controller - Regression tests', () => { languageRegistration.dispose(); model.dispose(); }); + + test('issue #37967: problem replacing consecutive characters', () => { + let model = createTextModel( + [ + 'const a = "foo";', + 'const b = ""' + ].join('\n') + ); + + withTestCodeEditor(null, { multiCursorMergeOverlapping: false, model: model }, (editor, cursor) => { + editor.setSelections([ + new Selection(1, 12, 1, 12), + new Selection(1, 16, 1, 16), + new Selection(2, 12, 2, 12), + new Selection(2, 13, 2, 13), + ]); + + CoreEditingCommands.DeleteLeft.runEditorCommand(null, editor, null); + + assertCursor(cursor, [ + new Selection(1, 11, 1, 11), + new Selection(1, 14, 1, 14), + new Selection(2, 11, 2, 11), + new Selection(2, 11, 2, 11), + ]); + + cursorCommand(cursor, H.Type, { text: '\'' }, 'keyboard'); + + assert.equal(model.getLineContent(1), 'const a = \'foo\';'); + assert.equal(model.getLineContent(2), 'const b = \'\''); + }); + + model.dispose(); + }); }); suite('Editor Controller - Cursor Configuration', () => { @@ -2092,8 +2059,7 @@ suite('Editor Controller - Cursor Configuration', () => { ' Third Line', '', '1' - ], - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + ] }, (model, cursor) => { CoreNavigationCommands.MoveTo.runCoreEditorCommand(cursor, { position: new Position(1, 21), source: 'keyboard' }); cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard'); @@ -2103,7 +2069,7 @@ suite('Editor Controller - Cursor Configuration', () => { }); test('Cursor honors insertSpaces configuration on tab', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ ' \tMy First Line\t ', 'My Second Line123', @@ -2112,12 +2078,7 @@ suite('Editor Controller - Cursor Configuration', () => { '1' ].join('\n'), { - isForSimpleWidget: false, - insertSpaces: true, tabSize: 13, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true } ); @@ -2186,8 +2147,7 @@ suite('Editor Controller - Cursor Configuration', () => { text: [ '\thello' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 1, 7, false); assertCursor(cursor, new Selection(1, 7, 1, 7)); @@ -2204,8 +2164,7 @@ suite('Editor Controller - Cursor Configuration', () => { text: [ '\thello' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 1, 7, false); assertCursor(cursor, new Selection(1, 7, 1, 7)); @@ -2222,8 +2181,7 @@ suite('Editor Controller - Cursor Configuration', () => { text: [ '\thell()' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 1, 7, false); assertCursor(cursor, new Selection(1, 7, 1, 7)); @@ -2240,11 +2198,6 @@ suite('Editor Controller - Cursor Configuration', () => { ' some line abc ' ], modelOpts: { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: false } }, (model, cursor) => { @@ -2267,15 +2220,7 @@ suite('Editor Controller - Cursor Configuration', () => { usingCursor({ text: [ ' ' - ], - modelOpts: { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ] }, (model, cursor) => { moveTo(cursor, 1, model.getLineContent(1).length + 1); cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard'); @@ -2295,14 +2240,6 @@ suite('Editor Controller - Cursor Configuration', () => { text: [ 'function foo (params: string) {}' ], - modelOpts: { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - }, languageIdentifier: mode.getLanguageIdentifier(), }, (model, cursor) => { @@ -2336,22 +2273,14 @@ suite('Editor Controller - Cursor Configuration', () => { }); test('removeAutoWhitespace on: removes only whitespace the cursor added 2', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ ' if (a) {', ' ', '', '', ' }' - ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { model: model }, (editor, cursor) => { @@ -2385,18 +2314,10 @@ suite('Editor Controller - Cursor Configuration', () => { }); test('removeAutoWhitespace on: test 1', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ ' some line abc ' - ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { model: model }, (editor, cursor) => { @@ -2450,20 +2371,12 @@ suite('Editor Controller - Cursor Configuration', () => { }); test('UseTabStops is off', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ ' x', ' a ', ' ' - ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { model: model, useTabStops: false }, (editor, cursor) => { @@ -2477,20 +2390,12 @@ suite('Editor Controller - Cursor Configuration', () => { }); test('Backspace removes whitespaces with tab size', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ ' \t \t x', ' a ', ' ' - ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - } + ].join('\n') ); withTestCodeEditor(null, { model: model, useTabStops: true }, (editor, cursor) => { @@ -2551,17 +2456,12 @@ suite('Editor Controller - Cursor Configuration', () => { }); test('PR #5423: Auto indent + undo + redo is funky', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ '' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true } ); @@ -2637,7 +2537,7 @@ suite('Editor Controller - Indentation Rules', () => { '\tif (true) {' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }, + modelOpts: { insertSpaces: false }, editorOpts: { autoIndent: true } }, (model, cursor) => { moveTo(cursor, 1, 12, false); @@ -2661,7 +2561,6 @@ suite('Editor Controller - Indentation Rules', () => { '\t' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }, editorOpts: { autoIndent: true } }, (model, cursor) => { moveTo(cursor, 2, 2, false); @@ -2680,7 +2579,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t\t\treturn true' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }, + modelOpts: { insertSpaces: false }, editorOpts: { autoIndent: true } }, (model, cursor) => { moveTo(cursor, 2, 15, false); @@ -2700,7 +2599,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t\t\t\treturn true' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }, + modelOpts: { insertSpaces: false }, editorOpts: { autoIndent: true } }, (model, cursor) => { moveTo(cursor, 2, 14, false); @@ -2718,18 +2617,13 @@ suite('Editor Controller - Indentation Rules', () => { }); test('Enter honors indentNextLinePattern 2', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'if (true)', '\tif (true)' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, mode.getLanguageIdentifier() ); @@ -2758,7 +2652,6 @@ suite('Editor Controller - Indentation Rules', () => { '}}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }, editorOpts: { autoIndent: true } }, (model, cursor) => { moveTo(cursor, 3, 13, false); @@ -2779,7 +2672,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}a}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 4, 3, false); moveTo(cursor, 4, 4, true); @@ -2798,7 +2691,7 @@ suite('Editor Controller - Indentation Rules', () => { '\tif (true) {' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 2, 12, false); moveTo(cursor, 2, 13, true); @@ -2819,7 +2712,6 @@ suite('Editor Controller - Indentation Rules', () => { '\tif (true) {' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } }, (model, cursor) => { moveTo(cursor, 1, 12, false); assertCursor(cursor, new Selection(1, 12, 1, 12)); @@ -2844,7 +2736,6 @@ suite('Editor Controller - Indentation Rules', () => { ' if (true) {' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } }, (model, cursor) => { moveTo(cursor, 1, 12, false); assertCursor(cursor, new Selection(1, 12, 1, 12)); @@ -2868,7 +2759,7 @@ suite('Editor Controller - Indentation Rules', () => { ' if (true) {' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 1, 12, false); assertCursor(cursor, new Selection(1, 12, 1, 12)); @@ -2896,7 +2787,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }, + modelOpts: { insertSpaces: false }, editorOpts: { autoIndent: true } }, (model, cursor) => { moveTo(cursor, 5, 4, false); @@ -2917,7 +2808,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}a}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 3, 9, false); assertCursor(cursor, new Selection(3, 9, 3, 9)); @@ -2937,7 +2828,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}a}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 3, 3, false); assertCursor(cursor, new Selection(3, 3, 3, 3)); @@ -2956,8 +2847,7 @@ suite('Editor Controller - Indentation Rules', () => { ' return true;', ' }a}' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 3, 11, false); assertCursor(cursor, new Selection(3, 11, 3, 11)); @@ -2977,7 +2867,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}a}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 3, 2, false); assertCursor(cursor, new Selection(3, 2, 3, 2)); @@ -3004,7 +2894,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t\t}a}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 3, 4, false); assertCursor(cursor, new Selection(3, 4, 3, 4)); @@ -3030,8 +2920,7 @@ suite('Editor Controller - Indentation Rules', () => { ' return true;', '}a}' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 3, 2, false); assertCursor(cursor, new Selection(3, 2, 3, 2)); @@ -3061,7 +2950,7 @@ suite('Editor Controller - Indentation Rules', () => { '}a}' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { tabSize: 2 } }, (model, cursor) => { moveTo(cursor, 3, 3, false); assertCursor(cursor, new Selection(3, 3, 3, 3)); @@ -3087,7 +2976,7 @@ suite('Editor Controller - Indentation Rules', () => { '' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { tabSize: 2 } }, (model, cursor) => { moveTo(cursor, 3, 5, false); moveTo(cursor, 4, 3, true); @@ -3108,12 +2997,7 @@ suite('Editor Controller - Indentation Rules', () => { '}' ], modelOpts: { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, languageIdentifier: mode.getLanguageIdentifier(), }, (model, cursor) => { @@ -3136,12 +3020,7 @@ suite('Editor Controller - Indentation Rules', () => { '}' ], modelOpts: { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, languageIdentifier: mode.getLanguageIdentifier(), }, (model, cursor) => { @@ -3165,7 +3044,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}', '?>' ], - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 5, 3, false); assertCursor(cursor, new Selection(5, 3, 5, 3)); @@ -3184,7 +3063,7 @@ suite('Editor Controller - Indentation Rules', () => { ' return 5;', ' ' ], - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + modelOpts: { insertSpaces: false } }, (model, cursor) => { moveTo(cursor, 3, 2, false); assertCursor(cursor, new Selection(3, 2, 3, 2)); @@ -3196,7 +3075,7 @@ suite('Editor Controller - Indentation Rules', () => { }); test('bug #16543: Tab should indent to correct indentation spot immediately', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'function baz() {', '\tfunction hello() { // something here', @@ -3206,12 +3085,7 @@ suite('Editor Controller - Indentation Rules', () => { '}' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, mode.getLanguageIdentifier() ); @@ -3229,7 +3103,7 @@ suite('Editor Controller - Indentation Rules', () => { test('bug #2938 (1): When pressing Tab on white-space only lines, indent straight to the right spot (similar to empty lines)', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ '\tfunction baz() {', '\t\tfunction hello() { // something here', @@ -3239,12 +3113,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, mode.getLanguageIdentifier() ); @@ -3262,7 +3131,7 @@ suite('Editor Controller - Indentation Rules', () => { test('bug #2938 (2): When pressing Tab on white-space only lines, indent straight to the right spot (similar to empty lines)', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ '\tfunction baz() {', '\t\tfunction hello() { // something here', @@ -3272,12 +3141,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, mode.getLanguageIdentifier() ); @@ -3294,7 +3158,7 @@ suite('Editor Controller - Indentation Rules', () => { }); test('bug #2938 (3): When pressing Tab on white-space only lines, indent straight to the right spot (similar to empty lines)', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ '\tfunction baz() {', '\t\tfunction hello() { // something here', @@ -3304,12 +3168,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, mode.getLanguageIdentifier() ); @@ -3326,7 +3185,7 @@ suite('Editor Controller - Indentation Rules', () => { }); test('bug #2938 (4): When pressing Tab on white-space only lines, indent straight to the right spot (similar to empty lines)', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ '\tfunction baz() {', '\t\tfunction hello() { // something here', @@ -3336,12 +3195,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t}' ].join('\n'), { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, insertSpaces: false, - tabSize: 4, - trimAutoWhitespace: true }, mode.getLanguageIdentifier() ); @@ -3359,7 +3213,7 @@ suite('Editor Controller - Indentation Rules', () => { test('bug #31015: When pressing Tab on lines and Enter rules are avail, indent straight to the right spotTab', () => { let mode = new OnEnterMode(IndentAction.Indent); - let model = TextModel.createFromString( + let model = createTextModel( [ ' if (a) {', ' ', @@ -3367,14 +3221,7 @@ suite('Editor Controller - Indentation Rules', () => { '', ' }' ].join('\n'), - { - isForSimpleWidget: false, - insertSpaces: true, - tabSize: 4, - detectIndentation: false, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true - }, + undefined, mode.getLanguageIdentifier() ); @@ -3397,21 +3244,14 @@ suite('Editor Controller - Indentation Rules', () => { increaseIndentPattern: /^\s*((begin|class|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while)|(.*\sdo\b))\b[^\{;]*$/, decreaseIndentPattern: /^\s*([}\]]([,)]?\s*(#|$)|\.[a-zA-Z_]\w*\b)|(end|rescue|ensure|else|elsif|when)\b)/ }); - let model = TextModel.createFromString( + let model = createTextModel( [ 'class Greeter', ' def initialize(name)', ' @name = name', ' en' ].join('\n'), - { - isForSimpleWidget: false, - defaultEOL: DefaultEndOfLine.LF, - detectIndentation: false, - insertSpaces: true, - tabSize: 2, - trimAutoWhitespace: true - }, + undefined, rubyMode.getLanguageIdentifier() ); @@ -3436,8 +3276,7 @@ suite('Editor Controller - Indentation Rules', () => { '\t\tconsole.log()', '\t}' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 5, 3, false); assertCursor(cursor, new Selection(5, 3, 5, 3)); @@ -3458,8 +3297,7 @@ suite('Editor Controller - Indentation Rules', () => { ') {', '}' ], - languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true } + languageIdentifier: mode.getLanguageIdentifier() }, (model, cursor) => { moveTo(cursor, 2, 3, false); assertCursor(cursor, new Selection(2, 3, 2, 3)); @@ -3478,7 +3316,6 @@ suite('Editor Controller - Indentation Rules', () => { '\t\t' ], languageIdentifier: mode.getLanguageIdentifier(), - modelOpts: { isForSimpleWidget: false, insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }, editorOpts: { autoIndent: true } }, (model, cursor) => { moveTo(cursor, 3, 3, false); @@ -3537,7 +3374,7 @@ suite('Editor Controller - Indentation Rules', () => { } let mode = new JSMode(); - let model = TextModel.createFromString( + let model = createTextModel( [ 'class ItemCtrl {', ' getPropertiesByItemId(id) {', @@ -3597,7 +3434,7 @@ suite('Editor Controller - Indentation Rules', () => { } let mode = new CppMode(); - let model = TextModel.createFromString( + let model = createTextModel( [ 'int main() {', ' return 0;', @@ -3609,7 +3446,7 @@ suite('Editor Controller - Indentation Rules', () => { '', ')', ].join('\n'), - { isForSimpleWidget: false, insertSpaces: true, detectIndentation: false, tabSize: 2, trimAutoWhitespace: false, defaultEOL: DefaultEndOfLine.LF }, + { tabSize: 2 }, mode.getLanguageIdentifier() ); @@ -3642,12 +3479,12 @@ suite('Editor Controller - Indentation Rules', () => { interface ICursorOpts { text: string[]; languageIdentifier?: LanguageIdentifier; - modelOpts?: ITextModelCreationOptions; + modelOpts?: IRelaxedTextModelCreationOptions; editorOpts?: IEditorOptions; } function usingCursor(opts: ICursorOpts, callback: (model: TextModel, cursor: Cursor) => void): void { - let model = TextModel.createFromString(opts.text.join('\n'), opts.modelOpts, opts.languageIdentifier); + let model = createTextModel(opts.text.join('\n'), opts.modelOpts, opts.languageIdentifier); model.forceTokenization(model.getLineCount()); let config = new TestConfiguration(opts.editorOpts); let viewModel = new ViewModel(0, config, model, null); @@ -4209,7 +4046,7 @@ suite('autoClosingPairs', () => { test('All cursors should do the same thing when deleting left', () => { let mode = new AutoClosingMode(); - let model = TextModel.createFromString( + let model = createTextModel( [ 'var a = ()' ].join('\n'), @@ -4233,7 +4070,7 @@ suite('autoClosingPairs', () => { }); test('issue #7100: Mouse word selection is strange when non-word character is at the end of line', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'before.a', 'before', @@ -4263,7 +4100,7 @@ suite('autoClosingPairs', () => { suite('Undo stops', () => { test('there is an undo stop between typing and deleting left', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'A line', 'Another line', @@ -4292,7 +4129,7 @@ suite('Undo stops', () => { }); test('there is an undo stop between typing and deleting right', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'A line', 'Another line', @@ -4321,7 +4158,7 @@ suite('Undo stops', () => { }); test('there is an undo stop between deleting left and typing', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'A line', 'Another line', @@ -4355,7 +4192,7 @@ suite('Undo stops', () => { }); test('there is an undo stop between deleting left and deleting right', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'A line', 'Another line', @@ -4393,7 +4230,7 @@ suite('Undo stops', () => { }); test('there is an undo stop between deleting right and typing', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'A line', 'Another line', @@ -4424,7 +4261,7 @@ suite('Undo stops', () => { }); test('there is an undo stop between deleting right and deleting left', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'A line', 'Another line', @@ -4460,7 +4297,7 @@ suite('Undo stops', () => { }); test('inserts undo stop when typing space', () => { - let model = TextModel.createFromString( + let model = createTextModel( [ 'A line', 'Another line', diff --git a/src/vs/editor/test/common/editorTestUtils.ts b/src/vs/editor/test/common/editorTestUtils.ts index cdc1b3f2aca..d2e8cb2072e 100644 --- a/src/vs/editor/test/common/editorTestUtils.ts +++ b/src/vs/editor/test/common/editorTestUtils.ts @@ -5,9 +5,37 @@ 'use strict'; import { TextModel } from 'vs/editor/common/model/textModel'; +import { DefaultEndOfLine, ITextModelCreationOptions } from 'vs/editor/common/model'; +import { LanguageIdentifier } from 'vs/editor/common/modes'; +import URI from 'vs/base/common/uri'; export function withEditorModel(text: string[], callback: (model: TextModel) => void): void { var model = TextModel.createFromString(text.join('\n')); callback(model); model.dispose(); } + +export interface IRelaxedTextModelCreationOptions { + tabSize?: number; + insertSpaces?: boolean; + detectIndentation?: boolean; + trimAutoWhitespace?: boolean; + defaultEOL?: DefaultEndOfLine; + isForSimpleWidget?: boolean; + largeFileSize?: number; + largeFileLineCount?: number; +} + +export function createTextModel(text: string, _options: IRelaxedTextModelCreationOptions = TextModel.DEFAULT_CREATION_OPTIONS, languageIdentifier: LanguageIdentifier = null, uri: URI = null): TextModel { + const options: ITextModelCreationOptions = { + tabSize: (typeof _options.tabSize === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.tabSize : _options.tabSize), + insertSpaces: (typeof _options.insertSpaces === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.insertSpaces : _options.insertSpaces), + detectIndentation: (typeof _options.detectIndentation === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.detectIndentation : _options.detectIndentation), + trimAutoWhitespace: (typeof _options.trimAutoWhitespace === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.trimAutoWhitespace : _options.trimAutoWhitespace), + defaultEOL: (typeof _options.defaultEOL === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.defaultEOL : _options.defaultEOL), + isForSimpleWidget: (typeof _options.isForSimpleWidget === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.isForSimpleWidget : _options.isForSimpleWidget), + largeFileSize: (typeof _options.largeFileSize === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.largeFileSize : _options.largeFileSize), + largeFileLineCount: (typeof _options.largeFileLineCount === 'undefined' ? TextModel.DEFAULT_CREATION_OPTIONS.largeFileLineCount : _options.largeFileLineCount), + }; + return TextModel.createFromString(text, options, languageIdentifier, uri); +} diff --git a/src/vs/editor/test/common/model/textModel.test.ts b/src/vs/editor/test/common/model/textModel.test.ts index 907e1460e72..e6d83dbe0ba 100644 --- a/src/vs/editor/test/common/model/textModel.test.ts +++ b/src/vs/editor/test/common/model/textModel.test.ts @@ -8,19 +8,16 @@ import * as assert from 'assert'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel'; -import { DefaultEndOfLine } from 'vs/editor/common/model'; import { UTF8_BOM_CHARACTER } from 'vs/base/common/strings'; +import { createTextModel } from 'vs/editor/test/common/editorTestUtils'; function testGuessIndentation(defaultInsertSpaces: boolean, defaultTabSize: number, expectedInsertSpaces: boolean, expectedTabSize: number, text: string[], msg?: string): void { - var m = TextModel.createFromString( + var m = createTextModel( text.join('\n'), { - isForSimpleWidget: false, tabSize: defaultTabSize, insertSpaces: defaultInsertSpaces, - detectIndentation: true, - defaultEOL: DefaultEndOfLine.LF, - trimAutoWhitespace: true + detectIndentation: true } ); var r = m.getOptions(); @@ -706,14 +703,9 @@ suite('Editor Model - TextModel', () => { }); test('normalizeIndentation 1', () => { - let model = TextModel.createFromString('', + let model = createTextModel('', { - isForSimpleWidget: false, - detectIndentation: false, - tabSize: 4, - insertSpaces: false, - trimAutoWhitespace: true, - defaultEOL: DefaultEndOfLine.LF + insertSpaces: false } ); @@ -743,16 +735,7 @@ suite('Editor Model - TextModel', () => { }); test('normalizeIndentation 2', () => { - let model = TextModel.createFromString('', - { - isForSimpleWidget: false, - detectIndentation: false, - tabSize: 4, - insertSpaces: true, - trimAutoWhitespace: true, - defaultEOL: DefaultEndOfLine.LF - } - ); + let model = createTextModel(''); assert.equal(model.normalizeIndentation('\ta'), ' a'); assert.equal(model.normalizeIndentation(' a'), ' a'); diff --git a/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts b/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts index e2c676defac..1ac0489684a 100644 --- a/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts +++ b/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts @@ -780,6 +780,9 @@ function createModel(text: string): ISimpleModel { getLineContent: (lineNumber: number) => { return text; }, + getLineLength: (lineNumber: number) => { + return text.length; + }, getLineMinColumn: (lineNumber: number) => { return 1; }, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 845e663d64c..bc94be7a993 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1488,6 +1488,10 @@ declare namespace monaco.editor { * Get the text for a certain line. */ getLineContent(lineNumber: number): string; + /** + * Get the text length for a certain line. + */ + getLineLength(lineNumber: number): number; /** * Get the text for all lines. */ @@ -2697,6 +2701,11 @@ declare namespace monaco.editor { * Defaults to 'alt' */ multiCursorModifier?: 'ctrlCmd' | 'alt'; + /** + * Merge overlapping selections. + * Defaults to true + */ + multiCursorMergeOverlapping?: boolean; /** * Configure the editor's accessibility support. * Defaults to 'auto'. It is best to leave this to 'auto'. @@ -3118,6 +3127,7 @@ declare namespace monaco.editor { readonly lineHeight: number; readonly readOnly: boolean; readonly multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; + readonly multiCursorMergeOverlapping: boolean; readonly wordSeparators: string; readonly autoClosingBrackets: boolean; readonly autoIndent: boolean; @@ -3255,6 +3265,7 @@ declare namespace monaco.editor { readonly readOnly: boolean; readonly accessibilitySupport: boolean; readonly multiCursorModifier: boolean; + readonly multiCursorMergeOverlapping: boolean; readonly wordSeparators: boolean; readonly autoClosingBrackets: boolean; readonly autoIndent: boolean; diff --git a/src/vs/platform/extensions/node/extensionValidator.ts b/src/vs/platform/extensions/node/extensionValidator.ts index 607507a7c44..0b98d38572d 100644 --- a/src/vs/platform/extensions/node/extensionValidator.ts +++ b/src/vs/platform/extensions/node/extensionValidator.ts @@ -223,7 +223,7 @@ export function isVersionValid(currentVersion: string, requestedVersion: string, let desiredVersion = normalizeVersion(parseVersion(requestedVersion)); if (!desiredVersion) { - notices.push(nls.localize('versionSyntax', "Could not parse `engines.vscode` value {0}. Please use, for example: ^0.10.0, ^1.2.3, ^0.11.0, ^0.10.x, etc.", requestedVersion)); + notices.push(nls.localize('versionSyntax', "Could not parse `engines.vscode` value {0}. Please use, for example: ^1.22.0, ^1.22.x, etc.", requestedVersion)); return false; } diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index a6d2eac1d88..51f62ad470e 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -12,7 +12,6 @@ import { isLinux } from 'vs/base/common/platform'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { Event } from 'vs/base/common/event'; import { startsWithIgnoreCase } from 'vs/base/common/strings'; -import { IProgress } from 'vs/platform/progress/common/progress'; import { IDisposable } from 'vs/base/common/lifecycle'; import { isEqualOrParent, isEqual } from 'vs/base/common/resources'; import { isUndefinedOrNull } from 'vs/base/common/types'; @@ -120,12 +119,6 @@ export interface IFileService { */ rename(resource: URI, newName: string): TPromise; - /** - * Creates a new empty file if the given path does not exist and otherwise - * will set the mtime and atime of the file to the current date. - */ - touchFile(resource: URI): TPromise; - /** * Deletes the provided file. The optional useTrash parameter allows to * move the file to trash. @@ -182,15 +175,13 @@ export interface IFileSystemProvider { // more... // - utimes(resource: URI, mtime: number, atime: number): TPromise; stat(resource: URI): TPromise; - read(resource: URI, offset: number, count: number, progress: IProgress): TPromise; - write(resource: URI, content: Uint8Array): TPromise; + readFile(resource: URI): TPromise; + writeFile(resource: URI, content: Uint8Array): TPromise; move(from: URI, to: URI): TPromise; mkdir(resource: URI): TPromise; readdir(resource: URI): TPromise<[URI, IStat][]>; - rmdir(resource: URI): TPromise; - unlink(resource: URI): TPromise; + delete(resource: URI): TPromise; } diff --git a/src/vs/platform/update/electron-main/updateService.darwin.ts b/src/vs/platform/update/electron-main/updateService.darwin.ts index 629ca60be86..aae291e1630 100644 --- a/src/vs/platform/update/electron-main/updateService.darwin.ts +++ b/src/vs/platform/update/electron-main/updateService.darwin.ts @@ -49,7 +49,7 @@ export class DarwinUpdateService extends AbstractUpdateService { protected setUpdateFeedUrl(quality: string): boolean { try { - electron.autoUpdater.setFeedURL({ url: createUpdateURL('darwin', quality) }); + electron.autoUpdater.setFeedURL(createUpdateURL('darwin', quality)); } catch (e) { // application is very likely not signed this.logService.error('Failed to set update feed URL'); diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 8142906c5ec..92b14c0281b 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -3680,6 +3680,17 @@ declare module 'vscode' { constructor(uri: Uri, rangeOrPosition: Range | Position); } + /** + * The event that is fired when diagnostics change. + */ + export interface DiagnosticChangeEvent { + + /** + * An array of resources for which diagnostics have changed. + */ + readonly uris: Uri[]; + } + /** * Represents the severity of diagnostics. */ @@ -6044,6 +6055,29 @@ declare module 'vscode' { */ export function match(selector: DocumentSelector, document: TextDocument): number; + /** + * An [event](#Event) which fires when the global set of diagnostics changes. This is + * newly added and removed diagnostics. + */ + export const onDidChangeDiagnostics: Event; + + /** + * Get all diagnostics for a given resource. *Note* that this includes diagnostics from + * all extensions but *not yet* from the task framework. + * + * @param resource A resource + * @returns An arrary of [diagnostics](#Diagnostic) objects or an empty array. + */ + export function getDiagnostics(resource: Uri): Diagnostic[]; + + /** + * Get all diagnostics. *Note* that this includes diagnostics from + * all extensions but *not yet* from the task framework. + * + * @returns An array of uri-diagnostics tuples or an empty array. + */ + export function getDiagnostics(): [Uri, Diagnostic[]][]; + /** * Create a diagnostics collection. * diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index b0d3245c026..39b89d30ede 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -11,32 +11,6 @@ declare module 'vscode' { export function sampleFunction(): Thenable; } - //#region Joh: readable diagnostics - - export interface DiagnosticChangeEvent { - uris: Uri[]; - } - - export namespace languages { - - /** - * - */ - export const onDidChangeDiagnostics: Event; - - /** - * - */ - export function getDiagnostics(resource: Uri): Diagnostic[]; - - /** - * - */ - export function getDiagnostics(): [Uri, Diagnostic[]][]; - } - - //#endregion - //#region Aeschli: folding export class FoldingRangeList { @@ -47,7 +21,7 @@ declare module 'vscode' { ranges: FoldingRange[]; /** - * Creates mew folding range list. + * Creates new folding range list. * * @param ranges The folding ranges */ @@ -211,7 +185,7 @@ declare module 'vscode' { readonly onDidChange?: Event; // more... - // + // @deprecated - will go away utimes(resource: Uri, mtime: number, atime: number): Thenable; stat(resource: Uri): Thenable; @@ -249,8 +223,41 @@ declare module 'vscode' { // create(resource: Uri): Thenable; } + // todo@joh discover files etc + // todo@joh CancellationToken everywhere + // todo@joh add open/close calls? + export interface FileSystemProvider2 { + + _version: 2; + + readonly onDidChange?: Event; + + stat(uri: Uri, token: CancellationToken): Thenable; + + readdir(uri: Uri, token: CancellationToken): Thenable<[Uri, FileStat][]>; + + readFile(uri: Uri, token: CancellationToken): Thenable; + + writeFile(uri: Uri, content: Uint8Array, token: CancellationToken): Thenable; + + // todo@remote + // Thenable + rename(oldUri: Uri, newUri: Uri): Thenable; + + // todo@remote + // helps with performance bigly + // copy?(from: Uri, to: Uri): Thenable; + + // todo@remote + // ? useTrash, expose trash + delete(resource: Uri, options: { recursive?: boolean; }): Thenable; + + // todo@remote + create(resource: Uri, options: { type: FileType }): Thenable; + } + export namespace workspace { - export function registerFileSystemProvider(scheme: string, provider: FileSystemProvider): Disposable; + export function registerFileSystemProvider(scheme: string, provider: FileSystemProvider, newProvider?: FileSystemProvider2): Disposable; } //#endregion @@ -558,7 +565,7 @@ declare module 'vscode' { readonly localResourceRoots?: Uri[]; } - export interface WebViewOnDidChangeViewStateEvent { + export interface WebviewOnDidChangeViewStateEvent { readonly viewColumn: ViewColumn; readonly active: boolean; } @@ -607,7 +614,7 @@ declare module 'vscode' { /** * Fired when the webview's view state changes. */ - readonly onDidChangeViewState: Event; + readonly onDidChangeViewState: Event; /** * Post a message to the webview content. diff --git a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts index 044af5fd345..3be13501b7d 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts @@ -6,7 +6,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import uri from 'vs/base/common/uri'; -import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData } from 'vs/workbench/parts/debug/common/debug'; +import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IAdapterExecutable } from 'vs/workbench/parts/debug/common/debug'; import { TPromise } from 'vs/base/common/winjs.base'; import { ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext, @@ -14,6 +14,9 @@ import { } from '../node/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import severity from 'vs/base/common/severity'; +import { AbstractDebugAdapter, convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/node/debugAdapter'; +import * as paths from 'vs/base/common/paths'; + @extHostNamedCustomer(MainContext.MainThreadDebugService) export class MainThreadDebugService implements MainThreadDebugServiceShape { @@ -21,6 +24,8 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape { private _proxy: ExtHostDebugServiceShape; private _toDispose: IDisposable[]; private _breakpointEventsActive: boolean; + private _debugAdapters: Map; + private _debugAdaptersHandleCounter = 1; constructor( extHostContext: IExtHostContext, @@ -46,6 +51,18 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape { } } })); + + this._debugAdapters = new Map(); + + // register a default DA provider + debugService.getConfigurationManager().registerDebugAdapterProvider('*', { + createDebugAdapter: (debugType, adapterInfo) => { + const handle = this._debugAdaptersHandleCounter++; + const da = new ExtensionHostDebugAdapter(handle, this._proxy, debugType, adapterInfo); + this._debugAdapters.set(handle, da); + return da; + } + }); } public dispose(): void { @@ -208,4 +225,59 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape { this.debugService.logToRepl(value, severity.Warning); return TPromise.wrap(undefined); } + + public $acceptDAMessage(handle: number, message: DebugProtocol.ProtocolMessage) { + + convertToVSCPaths(message, source => { + if (typeof source.path === 'object') { + source.path = uri.revive(source.path).toString(); + } + }); + + this._debugAdapters.get(handle).acceptMessage(message); + } + + public $acceptDAError(handle: number, name: string, message: string, stack: string) { + this._debugAdapters.get(handle).fireError(handle, new Error(`${name}: ${message}\n${stack}`)); + } + + public $acceptDAExit(handle: number, code: number, signal: string) { + this._debugAdapters.get(handle).fireExit(handle, code, signal); + } +} + +class ExtensionHostDebugAdapter extends AbstractDebugAdapter { + + constructor(private _handle: number, private _proxy: ExtHostDebugServiceShape, private _debugType: string, private _adapterExecutable: IAdapterExecutable | null) { + super(); + } + + public fireError(handle: number, err: Error) { + this._onError.fire(err); + } + + public fireExit(handle: number, code: number, signal: string) { + this._onExit.fire(code); + } + + public startSession(): TPromise { + return this._proxy.$startDASession(this._handle, this._debugType, this._adapterExecutable); + } + + public sendMessage(message: DebugProtocol.ProtocolMessage): void { + + convertToDAPaths(message, source => { + if (paths.isAbsolute(source.path)) { + (source).path = uri.file(source.path); + } else { + (source).path = uri.parse(source.path); + } + }); + + this._proxy.$sendDAMessage(this._handle, message); + } + + public stopSession(): TPromise { + return this._proxy.$stopDASession(this._handle); + } } diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 35ea17279f0..80ea36bc303 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -11,7 +11,6 @@ import { IFileService, IFileSystemProvider, IStat, IFileChange } from 'vs/platfo import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; -import { IProgress } from 'vs/platform/progress/common/progress'; import { ISearchResultProvider, ISearchQuery, ISearchComplete, ISearchProgressItem, QueryType, IFileMatch, ISearchService, ILineMatch } from 'vs/platform/search/common/search'; import { values } from 'vs/base/common/map'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; @@ -55,11 +54,6 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { $onFileSystemChange(handle: number, changes: IFileChangeDto[]): void { this._fileProvider.get(handle).$onFileSystemChange(changes); } - - $reportFileChunk(handle: number, session: number, base64Chunk: string): void { - this._fileProvider.get(handle).reportFileChunk(session, base64Chunk); - } - // --- search $handleFindMatch(handle: number, session, data: UriComponents | [UriComponents, ILineMatch]): void { @@ -67,23 +61,10 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { } } -class FileReadOperation { - - private static _idPool = 0; - - constructor( - readonly progress: IProgress, - readonly id: number = ++FileReadOperation._idPool - ) { - // - } -} - class RemoteFileSystemProvider implements IFileSystemProvider { private readonly _onDidChange = new Emitter(); private readonly _registrations: IDisposable[]; - private readonly _reads = new Map(); readonly onDidChange: Event = this._onDidChange.event; @@ -112,31 +93,22 @@ class RemoteFileSystemProvider implements IFileSystemProvider { // --- forwarding calls - utimes(resource: URI, mtime: number, atime: number): TPromise { - return this._proxy.$utimes(this._handle, resource, mtime, atime); - } stat(resource: URI): TPromise { return this._proxy.$stat(this._handle, resource); } - read(resource: URI, offset: number, count: number, progress: IProgress): TPromise { - const read = new FileReadOperation(progress); - this._reads.set(read.id, read); - return this._proxy.$read(this._handle, read.id, offset, count, resource).then(value => { - this._reads.delete(read.id); - return value; + readFile(resource: URI): TPromise { + return this._proxy.$readFile(this._handle, resource).then(encoded => { + return Buffer.from(encoded, 'base64'); }); } - reportFileChunk(session: number, encodedChunk: string): void { - this._reads.get(session).progress.report(Buffer.from(encodedChunk, 'base64')); - } - write(resource: URI, content: Uint8Array): TPromise { + writeFile(resource: URI, content: Uint8Array): TPromise { let encoded = Buffer.isBuffer(content) ? content.toString('base64') - : Buffer.from(content.buffer).toString('base64'); - return this._proxy.$write(this._handle, resource, encoded); + : Buffer.from(content.buffer, content.byteOffset, content.byteLength).toString('base64'); + return this._proxy.$writeFile(this._handle, resource, encoded); } - unlink(resource: URI): TPromise { - return this._proxy.$unlink(this._handle, resource); + delete(resource: URI): TPromise { + return this._proxy.$delete(this._handle, resource); } move(resource: URI, target: URI): TPromise { return this._proxy.$move(this._handle, resource, target); @@ -149,9 +121,6 @@ class RemoteFileSystemProvider implements IFileSystemProvider { return data.map(tuple => <[URI, IStat]>[URI.revive(tuple[0]), tuple[1]]); }); } - rmdir(resource: URI): TPromise { - return this._proxy.$rmdir(this._handle, resource); - } } class SearchOperation { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index a8e76e948ea..39e7fc810d1 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -107,7 +107,7 @@ export function createApiFactory( const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostHeapService, extHostLogService)); const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands)); rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); - const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace)); + const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService)); rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics)); @@ -239,9 +239,9 @@ export function createApiFactory( checkProposedApiEnabled(extension); return extHostDiagnostics.onDidChangeDiagnostics; }, - getDiagnostics: proposedApiFunction(extension, (resource?) => { - return extHostDiagnostics.getDiagnostics(resource); - }), + getDiagnostics: (resource?) => { + return extHostDiagnostics.getDiagnostics(resource); + }, getLanguages(): TPromise { return extHostLanguages.getLanguages(); }, @@ -543,8 +543,8 @@ export function createApiFactory( onDidEndTask: (listeners, thisArgs?, disposables?) => { return extHostTask.onDidEndTask(listeners, thisArgs, disposables); }, - registerFileSystemProvider: proposedApiFunction(extension, (scheme, provider) => { - return extHostFileSystem.registerFileSystemProvider(scheme, provider); + registerFileSystemProvider: proposedApiFunction(extension, (scheme, provider, newProvider?) => { + return extHostFileSystem.registerFileSystemProvider(scheme, provider, newProvider); }), registerSearchProvider: proposedApiFunction(extension, (scheme, provider) => { return extHostFileSystem.registerSearchProvider(scheme, provider); @@ -718,7 +718,7 @@ class Extension implements vscode.Extension { } activate(): Thenable { - return this._extensionService.activateById(this.id, new ExtensionActivatedByAPI(false)).then(() => this.exports); + return this._extensionService.activateByIdWithErrors(this.id, new ExtensionActivatedByAPI(false)).then(() => this.exports); } } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index c6b2eda75e7..549543189cf 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -394,7 +394,6 @@ export interface MainThreadFileSystemShape extends IDisposable { $unregisterProvider(handle: number): void; $onFileSystemChange(handle: number, resource: IFileChangeDto[]): void; - $reportFileChunk(handle: number, session: number, base64Encoded: string | null): void; $handleFindMatch(handle: number, session, data: UriComponents | [UriComponents, ILineMatch]): void; } @@ -471,6 +470,9 @@ export interface MainThreadSCMShape extends IDisposable { export type DebugSessionUUID = string; export interface MainThreadDebugServiceShape extends IDisposable { + $acceptDAMessage(handle: number, message: DebugProtocol.ProtocolMessage); + $acceptDAError(handle: number, name: string, message: string, stack: string); + $acceptDAExit(handle: number, code: number, signal: string); $registerDebugConfigurationProvider(type: string, hasProvideMethod: boolean, hasResolveMethod: boolean, hasDebugAdapterExecutable: boolean, handle: number): TPromise; $unregisterDebugConfigurationProvider(handle: number): TPromise; $startDebugging(folder: UriComponents | undefined, nameOrConfig: string | vscode.DebugConfiguration): TPromise; @@ -570,15 +572,17 @@ export interface ExtHostWorkspaceShape { } export interface ExtHostFileSystemShape { - $utimes(handle: number, resource: UriComponents, mtime: number, atime: number): TPromise; $stat(handle: number, resource: UriComponents): TPromise; - $read(handle: number, session: number, offset: number, count: number, resource: UriComponents): TPromise; - $write(handle: number, resource: UriComponents, base64Encoded: string): TPromise; - $unlink(handle: number, resource: UriComponents): TPromise; + + $readFile(handle: number, resource: UriComponents): TPromise; + $writeFile(handle: number, resource: UriComponents, base64Encoded: string): TPromise; + $move(handle: number, resource: UriComponents, target: UriComponents): TPromise; $mkdir(handle: number, resource: UriComponents): TPromise; $readdir(handle: number, resource: UriComponents): TPromise<[UriComponents, IStat][]>; - $rmdir(handle: number, resource: UriComponents): TPromise; + + $delete(handle: number, resource: UriComponents): TPromise; + $provideFileSearchResults(handle: number, session: number, query: string): TPromise; $provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, options: { includes: string[], excludes: string[] }): TPromise; } @@ -789,6 +793,9 @@ export interface ISourceMultiBreakpointDto { } export interface ExtHostDebugServiceShape { + $startDASession(handle: number, debugType: string, adapterExecutableInfo: IAdapterExecutable | null): TPromise; + $stopDASession(handle: number): TPromise; + $sendDAMessage(handle: number, message: DebugProtocol.ProtocolMessage): TPromise; $resolveDebugConfiguration(handle: number, folder: UriComponents | undefined, debugConfiguration: IConfig): TPromise; $provideDebugConfigurations(handle: number, folder: UriComponents | undefined): TPromise; $debugAdapterExecutable(handle: number, folder: UriComponents | undefined): TPromise; diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index 39e58cacd5f..9cd1acc2719 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -12,17 +12,18 @@ import { IMainContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, IFunctionBreakpointDto } from 'vs/workbench/api/node/extHost.protocol'; import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; - import * as vscode from 'vscode'; import URI, { UriComponents } from 'vs/base/common/uri'; import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint } from 'vs/workbench/api/node/extHostTypes'; import { generateUuid } from 'vs/base/common/uuid'; +import { DebugAdapter, convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/node/debugAdapter'; +import * as paths from 'vs/base/common/paths'; +import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; +import { IAdapterExecutable } from 'vs/workbench/parts/debug/common/debug'; export class ExtHostDebugService implements ExtHostDebugServiceShape { - private _workspace: ExtHostWorkspace; - private _handleCounter: number; private _handlers: Map; @@ -52,10 +53,10 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { private readonly _onDidChangeBreakpoints: Emitter; + private _debugAdapters: Map; - constructor(mainContext: IMainContext, workspace: ExtHostWorkspace) { - this._workspace = workspace; + constructor(mainContext: IMainContext, private _workspace: ExtHostWorkspace, private _extensionService: ExtHostExtensionService) { this._handleCounter = 0; this._handlers = new Map(); @@ -77,6 +78,51 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { this._breakpoints = new Map(); this._breakpointEventsActive = false; + + this._debugAdapters = new Map(); + } + + public $startDASession(handle: number, debugType: string, adpaterExecutable: IAdapterExecutable | null): TPromise { + const mythis = this; + + const da = new class extends DebugAdapter { + + // DA -> VS Code + public acceptMessage(message: DebugProtocol.ProtocolMessage) { + convertToVSCPaths(message, source => { + if (paths.isAbsolute(source.path)) { + (source).path = URI.file(source.path); + } + }); + mythis._debugServiceProxy.$acceptDAMessage(handle, message); + } + + }(debugType, adpaterExecutable, this._extensionService.getAllExtensionDescriptions()); + + this._debugAdapters.set(handle, da); + da.onError(err => this._debugServiceProxy.$acceptDAError(handle, err.name, err.message, err.stack)); + da.onExit(code => this._debugServiceProxy.$acceptDAExit(handle, code, null)); + return da.startSession(); + } + + public $sendDAMessage(handle: number, message: DebugProtocol.ProtocolMessage): TPromise { + // VS Code -> DA + convertToDAPaths(message, source => { + if (typeof source.path === 'object') { + source.path = URI.revive(source.path).fsPath; + } + }); + const da = this._debugAdapters.get(handle); + if (da) { + da.sendMessage(message); + } + return void 0; + } + + public $stopDASession(handle: number): TPromise { + const da = this._debugAdapters.get(handle); + this._debugAdapters.delete(handle); + return da ? da.stopSession() : void 0; } private startBreakpoints() { diff --git a/src/vs/workbench/api/node/extHostDiagnostics.ts b/src/vs/workbench/api/node/extHostDiagnostics.ts index 342060762d7..60f96a01f2e 100644 --- a/src/vs/workbench/api/node/extHostDiagnostics.ts +++ b/src/vs/workbench/api/node/extHostDiagnostics.ts @@ -229,6 +229,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape { } } } + Object.freeze(uris); return { uris }; } diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index e1979889222..c37e7b2dfe7 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -127,6 +127,7 @@ export class ExtensionActivationTimesBuilder { export class ActivatedExtension { public readonly activationFailed: boolean; + public readonly activationFailedError: Error; public readonly activationTimes: ExtensionActivationTimes; public readonly module: IExtensionModule; public readonly exports: IExtensionAPI; @@ -134,12 +135,14 @@ export class ActivatedExtension { constructor( activationFailed: boolean, + activationFailedError: Error, activationTimes: ExtensionActivationTimes, module: IExtensionModule, exports: IExtensionAPI, subscriptions: IDisposable[] ) { this.activationFailed = activationFailed; + this.activationFailedError = activationFailedError; this.activationTimes = activationTimes; this.module = module; this.exports = exports; @@ -149,13 +152,13 @@ export class ActivatedExtension { export class EmptyExtension extends ActivatedExtension { constructor(activationTimes: ExtensionActivationTimes) { - super(false, activationTimes, { activate: undefined, deactivate: undefined }, undefined, []); + super(false, null, activationTimes, { activate: undefined, deactivate: undefined }, undefined, []); } } export class FailedExtension extends ActivatedExtension { - constructor(activationTimes: ExtensionActivationTimes) { - super(true, activationTimes, { activate: undefined, deactivate: undefined }, undefined, []); + constructor(activationError: Error) { + super(true, activationError, ExtensionActivationTimes.NONE, { activate: undefined, deactivate: undefined }, undefined, []); } } @@ -244,7 +247,8 @@ export class ExtensionsActivator { if (!depDesc) { // Error condition 1: unknown dependency this._host.showMessage(Severity.Error, nls.localize('unknownDep', "Extension '{1}' failed to activate. Reason: unknown dependency '{0}'.", depId, currentExtension.id)); - this._activatedExtensions[currentExtension.id] = new FailedExtension(ExtensionActivationTimes.NONE); + const error = new Error(`Unknown dependency '${depId}'`); + this._activatedExtensions[currentExtension.id] = new FailedExtension(error); return; } @@ -253,7 +257,9 @@ export class ExtensionsActivator { if (dep.activationFailed) { // Error condition 2: a dependency has already failed activation this._host.showMessage(Severity.Error, nls.localize('failedDep1', "Extension '{1}' failed to activate. Reason: dependency '{0}' failed to activate.", depId, currentExtension.id)); - this._activatedExtensions[currentExtension.id] = new FailedExtension(ExtensionActivationTimes.NONE); + const error = new Error(`Dependency ${depId} failed to activate`); + (error).detail = dep.activationFailedError; + this._activatedExtensions[currentExtension.id] = new FailedExtension(error); return; } } else { @@ -286,7 +292,8 @@ export class ExtensionsActivator { for (let i = 0, len = extensionDescriptions.length; i < len; i++) { // Error condition 3: dependency loop this._host.showMessage(Severity.Error, nls.localize('failedDep2', "Extension '{0}' failed to activate. Reason: more than 10 levels of dependencies (most likely a dependency loop).", extensionDescriptions[i].id)); - this._activatedExtensions[extensionDescriptions[i].id] = new FailedExtension(ExtensionActivationTimes.NONE); + const error = new Error('More than 10 levels of dependencies (most likely a dependency loop)'); + this._activatedExtensions[extensionDescriptions[i].id] = new FailedExtension(error); } return TPromise.as(void 0); } @@ -334,7 +341,7 @@ export class ExtensionsActivator { console.error('Activating extension `' + extensionDescription.id + '` failed: ', err.message); console.log('Here is the error stack: ', err.stack); // Treat the extension as being empty - return new FailedExtension(ExtensionActivationTimes.NONE); + return new FailedExtension(err); }).then((x: ActivatedExtension) => { this._activatedExtensions[extensionDescription.id] = x; delete this._activatingExtensions[extensionDescription.id]; diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 25e95031280..8d3d62d08fb 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -208,6 +208,17 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } } + public activateByIdWithErrors(extensionId: string, reason: ExtensionActivationReason): TPromise { + return this.activateById(extensionId, reason).then(() => { + const extension = this._activator.getActivatedExtension(extensionId); + if (extension.activationFailed) { + // activation failed => bubble up the error as the promise result + return TPromise.wrapError(extension.activationFailedError); + } + return void 0; + }); + } + public getAllExtensionDescriptions(): IExtensionDescription[] { return this._registry.getAllExtensionDescriptions(); } @@ -371,7 +382,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { }; return this._callActivateOptional(logService, extensionId, extensionModule, context, activationTimesBuilder).then((extensionExports) => { - return new ActivatedExtension(false, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions); + return new ActivatedExtension(false, null, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions); }); } diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 5d8499e44fb..aa5115926ea 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -13,9 +13,8 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { asWinJsPromise } from 'vs/base/common/async'; import { IPatternInfo } from 'vs/platform/search/common/search'; import { values } from 'vs/base/common/map'; -import { Range } from 'vs/workbench/api/node/extHostTypes'; +import { Range, FileType } from 'vs/workbench/api/node/extHostTypes'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; -import { IProgress } from 'vs/platform/progress/common/progress'; class FsLinkProvider implements vscode.DocumentLinkProvider { @@ -56,10 +55,67 @@ class FsLinkProvider implements vscode.DocumentLinkProvider { } } + +class FileSystemProviderShim implements vscode.FileSystemProvider2 { + + _version: 2; + + onDidChange?: vscode.Event; + + constructor(private readonly _delegate: vscode.FileSystemProvider) { + this.onDidChange = this._delegate.onDidChange; + } + + stat(resource: vscode.Uri): Thenable { + return this._delegate.stat(resource); + } + rename(oldUri: vscode.Uri, newUri: vscode.Uri): Thenable { + return this._delegate.move(oldUri, newUri); + } + readdir(resource: vscode.Uri): Thenable<[vscode.Uri, vscode.FileStat][]> { + return this._delegate.readdir(resource); + } + + // --- delete/create file or folder + + delete(resource: vscode.Uri, options: { recursive: boolean; }): Thenable { + return this.stat(resource).then(stat => { + if (stat.type === FileType.Dir) { + return this._delegate.rmdir(resource); + } else { + return this._delegate.unlink(resource); + } + }); + } + create(resource: vscode.Uri, options: { type: vscode.FileType; }): Thenable { + if (options.type === FileType.Dir) { + return this._delegate.mkdir(resource); + } else { + return this._delegate.write(resource, Buffer.from([])).then(() => this._delegate.stat(resource)); + } + } + + // --- read/write + + readFile(resource: vscode.Uri): Thenable { + let chunks: Buffer[] = []; + return this._delegate.read(resource, 0, -1, { + report(data) { + chunks.push(Buffer.from(data)); + } + }).then(() => { + return Buffer.concat(chunks); + }); + } + writeFile(resource: vscode.Uri, content: Uint8Array): Thenable { + return this._delegate.write(resource, content); + } +} + export class ExtHostFileSystem implements ExtHostFileSystemShape { private readonly _proxy: MainThreadFileSystemShape; - private readonly _fsProvider = new Map(); + private readonly _fsProvider = new Map(); private readonly _searchProvider = new Map(); private readonly _linkProvider = new FsLinkProvider(); @@ -70,7 +126,15 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { extHostLanguageFeatures.registerDocumentLinkProvider('*', this._linkProvider); } - registerFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider) { + registerFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider, newProvider: vscode.FileSystemProvider2) { + if (newProvider && newProvider._version === 2) { + return this._doRegisterFileSystemProvider(scheme, newProvider); + } else { + return this._doRegisterFileSystemProvider(scheme, new FileSystemProviderShim(provider)); + } + } + + private _doRegisterFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider2) { const handle = this._handlePool++; this._linkProvider.add(scheme); this._fsProvider.set(handle, provider); @@ -103,42 +167,32 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { }; } - $utimes(handle: number, resource: UriComponents, mtime: number, atime: number): TPromise { - return asWinJsPromise(token => this._fsProvider.get(handle).utimes(URI.revive(resource), mtime, atime)); - } $stat(handle: number, resource: UriComponents): TPromise { - return asWinJsPromise(token => this._fsProvider.get(handle).stat(URI.revive(resource))); - } - $read(handle: number, session: number, offset: number, count: number, resource: UriComponents): TPromise { - const progress: IProgress = { - report: chunk => { - let base64Chunk = Buffer.isBuffer(chunk) - ? chunk.toString('base64') - : Buffer.from(chunk.buffer).toString('base64'); - - this._proxy.$reportFileChunk(handle, session, base64Chunk); - } - }; - return asWinJsPromise(token => this._fsProvider.get(handle).read(URI.revive(resource), offset, count, progress)); - } - $write(handle: number, resource: UriComponents, base64Content: string): TPromise { - return asWinJsPromise(token => this._fsProvider.get(handle).write(URI.revive(resource), Buffer.from(base64Content, 'base64'))); - } - $unlink(handle: number, resource: UriComponents): TPromise { - return asWinJsPromise(token => this._fsProvider.get(handle).unlink(URI.revive(resource))); - } - $move(handle: number, resource: UriComponents, target: UriComponents): TPromise { - return asWinJsPromise(token => this._fsProvider.get(handle).move(URI.revive(resource), URI.revive(target))); - } - $mkdir(handle: number, resource: UriComponents): TPromise { - return asWinJsPromise(token => this._fsProvider.get(handle).mkdir(URI.revive(resource))); + return asWinJsPromise(token => this._fsProvider.get(handle).stat(URI.revive(resource), token)); } $readdir(handle: number, resource: UriComponents): TPromise<[UriComponents, IStat][], any> { - return asWinJsPromise(token => this._fsProvider.get(handle).readdir(URI.revive(resource))); + return asWinJsPromise(token => this._fsProvider.get(handle).readdir(URI.revive(resource), token)); } - $rmdir(handle: number, resource: UriComponents): TPromise { - return asWinJsPromise(token => this._fsProvider.get(handle).rmdir(URI.revive(resource))); + $readFile(handle: number, resource: UriComponents): TPromise { + return asWinJsPromise(token => { + return this._fsProvider.get(handle).readFile(URI.revive(resource), token); + }).then(data => { + return Buffer.isBuffer(data) ? data.toString('base64') : Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('base64'); + }); } + $writeFile(handle: number, resource: UriComponents, base64Content: string): TPromise { + return asWinJsPromise(token => this._fsProvider.get(handle).writeFile(URI.revive(resource), Buffer.from(base64Content, 'base64'), token)); + } + $delete(handle: number, resource: UriComponents): TPromise { + return asWinJsPromise(token => this._fsProvider.get(handle).delete(URI.revive(resource), { recursive: true })); + } + $move(handle: number, oldUri: UriComponents, newUri: UriComponents): TPromise { + return asWinJsPromise(token => this._fsProvider.get(handle).rename(URI.revive(oldUri), URI.revive(newUri))); + } + $mkdir(handle: number, resource: UriComponents): TPromise { + return asWinJsPromise(token => this._fsProvider.get(handle).create(URI.revive(resource), { type: FileType.Dir })); + } + $provideFileSearchResults(handle: number, session: number, query: string): TPromise { const provider = this._searchProvider.get(handle); if (!provider.provideFileSearchResults) { diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 6ddf8382e36..393af8d3101 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -30,8 +30,8 @@ export class ExtHostWebview implements vscode.Webview { public readonly onDisposeEmitter = new Emitter(); public readonly onDidDispose: Event = this.onDisposeEmitter.event; - public readonly onDidChangeViewStateEmitter = new Emitter(); - public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; + public readonly onDidChangeViewStateEmitter = new Emitter(); + public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; constructor( handle: WebviewHandle, diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index 88d2d8d3f25..7fd58a461ac 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -362,7 +362,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { if (token) { token.onCancellationRequested(() => this._proxy.$cancelSearch(requestId)); } - return result.then(data => data.map(URI.revive)); + return result.then(data => Array.isArray(data) ? data.map(URI.revive) : []); } saveAll(includeUntitled?: boolean): Thenable { diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 298b44a0160..00530bb346e 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -24,15 +24,12 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility'; -import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme'; import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar'; import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; -import { isMacintosh } from 'vs/base/common/platform'; -import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { Dimension, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; -import { Color } from 'vs/base/common/color'; +import { Dimension } from 'vs/base/browser/dom'; export class ActivitybarPart extends Part { @@ -60,8 +57,7 @@ export class ActivitybarPart extends Part { @IContextMenuService private contextMenuService: IContextMenuService, @IInstantiationService private instantiationService: IInstantiationService, @IPartService private partService: IPartService, - @IThemeService themeService: IThemeService, - @ILifecycleService private lifecycleService: ILifecycleService + @IThemeService themeService: IThemeService ) { super(id, { hasTitle: false }, themeService); @@ -135,27 +131,6 @@ export class ActivitybarPart extends Part { // Top Actionbar with action items for each viewlet action this.createGlobalActivityActionBar($('.global-activity').appendTo($result).getHTMLElement()); - // TODO@Ben: workaround for https://github.com/Microsoft/vscode/issues/45700 - // It looks like there are rendering glitches on macOS with Chrome 61 when - // using --webkit-mask with a background color that is different from the image - // The workaround is to promote the element onto its own drawing layer. We do - // this only after the workbench has loaded because otherwise there is ugly flicker. - if (isMacintosh) { - this.lifecycleService.when(LifecyclePhase.Running).then(() => { - scheduleAtNextAnimationFrame(() => { // another delay... - scheduleAtNextAnimationFrame(() => { // ...to prevent more flickering on startup - registerThemingParticipant((theme, collector) => { - const activityBarForeground = theme.getColor(ACTIVITY_BAR_FOREGROUND); - if (activityBarForeground && !activityBarForeground.equals(Color.white)) { - // only apply this workaround if the color is different from the image one (white) - collector.addRule('.monaco-workbench .activitybar > .content > .composite-bar > .monaco-action-bar .action-label { will-change: transform; }'); - } - }); - }); - }); - }); - } - return $result.getHTMLElement(); } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 9f79d7af329..460a1fe6824 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -102,6 +102,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService private forceHideTabs: boolean; private doNotFireTabOptionsChanged: boolean; private revealIfOpen: boolean; + private ignoreOpenEditorErrors: boolean; private _onEditorsChanged: ThrottledEmitter; private readonly _onEditorOpening: Emitter; @@ -546,8 +547,9 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Stop loading promise if any monitor.cancel(); - // Report error only if this was not us restoring previous error state - if (this.partService.isCreated() && !errors.isPromiseCanceledError(error)) { + // Report error only if this was not us restoring previous error state or + // we are told to ignore errors that occur from opening an editor + if (this.partService.isCreated() && !errors.isPromiseCanceledError(error) && !this.ignoreOpenEditorErrors) { const actions: INotificationActions = { primary: [] }; if (errors.isErrorWithActions(error)) { actions.primary = (error as errors.IErrorWithActions).actions; @@ -569,7 +571,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Recover by closing the active editor (if the input is still the active one) if (group.activeEditor === input) { - this.doCloseActiveEditor(group, !(options && options.preserveFocus) /* still preserve focus as needed */); + this.doCloseActiveEditor(group, !(options && options.preserveFocus) /* still preserve focus as needed */, true /* from error */); } } @@ -603,7 +605,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } } - private doCloseActiveEditor(group: EditorGroup, focusNext = true): void { + private doCloseActiveEditor(group: EditorGroup, focusNext = true, fromError?: boolean): void { const position = this.stacks.positionOfGroup(group); // Update stacks model @@ -616,7 +618,22 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Otherwise open next active else { - this.openEditor(group.activeEditor, !focusNext ? EditorOptions.create({ preserveFocus: true }) : null, position).done(null, errors.onUnexpectedError); + // When closing an editor due to an error we can end up in a loop where we continue closing + // editors that fail to open (e.g. when the file no longer exists). We do not want to show + // repeated errors in this case to the user. As such, if we open the next editor and we are + // in a scope of a previous editor failing, we silence the input errors until the editor is + // opened. + if (fromError) { + this.ignoreOpenEditorErrors = true; + } + + this.openEditor(group.activeEditor, !focusNext ? EditorOptions.create({ preserveFocus: true }) : null, position).done(() => { + this.ignoreOpenEditorErrors = false; + }, error => { + errors.onUnexpectedError(error); + + this.ignoreOpenEditorErrors = false; + }); } } diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index 93112309b92..c34ea66ab5a 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -294,17 +294,17 @@ export class WorkbenchShell { } perf.mark('willReadLocalStorage'); - const readyToSend = this.storageService.getBoolean('localStorageMetricsReadyToSend3'); + const readyToSend = this.storageService.getBoolean('localStorageMetricsReadyToSend2'); perf.mark('didReadLocalStorage'); if (!readyToSend) { - this.storageService.store('localStorageMetricsReadyToSend3', true); + this.storageService.store('localStorageMetricsReadyToSend2', true); return; // avoid logging localStorage metrics directly after the update, we prefer cold startup numbers } - if (!this.storageService.getBoolean('localStorageMetricsSent3')) { + if (!this.storageService.getBoolean('localStorageMetricsSent2')) { perf.mark('willWriteLocalStorage'); - this.storageService.store('localStorageMetricsSent3', true); + this.storageService.store('localStorageMetricsSent2', true); perf.mark('didWriteLocalStorage'); perf.mark('willStatLocalStorage'); diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 5524d16960d..3b3e4856a4f 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -20,6 +20,7 @@ import { Range, IRange } from 'vs/editor/common/core/range'; import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IDisposable } from 'vs/base/common/lifecycle'; export const VIEWLET_ID = 'workbench.view.debug'; export const VARIABLES_VIEW_ID = 'workbench.debug.variablesView'; @@ -347,6 +348,7 @@ export interface IDebugConfiguration { hideActionBar: boolean; showInStatusBar: 'never' | 'always' | 'onFirstSessionStart'; internalConsoleOptions: 'neverOpen' | 'openOnSessionStart' | 'openOnFirstSessionStart'; + extensionHostDebugAdapter: boolean; } export interface IGlobalConfig { @@ -380,6 +382,22 @@ export interface ICompound { configurations: (string | { name: string, folder: string })[]; } +export interface IDebugAdapter extends IDisposable { + readonly onError: Event; + readonly onExit: Event; + onRequest(callback: (request: DebugProtocol.Request) => void); + onEvent(callback: (event: DebugProtocol.Event) => void); + startSession(): TPromise; + sendMessage(message: DebugProtocol.ProtocolMessage): void; + sendResponse(response: DebugProtocol.Response): void; + sendRequest(command: string, args: any, clb: (result: DebugProtocol.Response) => void): void; + stopSession(): TPromise; +} + +export interface IDebugAdapterProvider { + createDebugAdapter(debugType: string, adapterInfo: IAdapterExecutable | null): IDebugAdapter; +} + export interface IAdapterExecutable { command?: string; args?: string[]; @@ -448,6 +466,9 @@ export interface IConfigurationManager { resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: any): TPromise; debugAdapterExecutable(folderUri: uri | undefined, type: string): TPromise; + + registerDebugAdapterProvider(debugType: string, debugAdapterLauncher: IDebugAdapterProvider); + createDebugAdapter(debugType: string, adapterExecutable: IAdapterExecutable | null): IDebugAdapter; } export interface ILaunch { diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index d808ca71e7e..2b6f3550af8 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -209,6 +209,11 @@ configurationRegistry.registerConfiguration({ description: nls.localize({ comment: ['This is the description for a setting'], key: 'launch' }, "Global debug launch configuration. Should be used as an alternative to 'launch.json' that is shared across workspaces"), default: { configurations: [], compounds: [] }, $ref: launchSchemaId + }, + 'debug.extensionHostDebugAdapter': { + type: 'boolean', + description: nls.localize({ comment: ['This is the description for a setting'], key: 'extensionHostDebugAdapter' }, "Run debug adapter in extension host"), + default: false } } }); diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index 2ab01a3c8af..65284696d54 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -26,8 +26,8 @@ import { IFileService } from 'vs/platform/files/common/files'; import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IDebugConfigurationProvider, IRawAdapter, ICompound, IDebugConfiguration, IConfig, IEnvConfig, IGlobalConfig, IConfigurationManager, ILaunch, IAdapterExecutable } from 'vs/workbench/parts/debug/common/debug'; -import { Adapter } from 'vs/workbench/parts/debug/node/debugAdapter'; +import { IDebugConfigurationProvider, IRawAdapter, ICompound, IDebugConfiguration, IConfig, IEnvConfig, IGlobalConfig, IConfigurationManager, ILaunch, IAdapterExecutable, IDebugAdapterProvider, IDebugAdapter } from 'vs/workbench/parts/debug/common/debug'; +import { Debugger } from 'vs/workbench/parts/debug/node/debugger'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; @@ -221,7 +221,7 @@ const DEBUG_SELECTED_CONFIG_NAME_KEY = 'debug.selectedconfigname'; const DEBUG_SELECTED_ROOT = 'debug.selectedroot'; export class ConfigurationManager implements IConfigurationManager { - private adapters: Adapter[]; + private debuggers: Debugger[]; private breakpointModeIdsSet = new Set(); private launches: ILaunch[]; private selectedName: string; @@ -229,6 +229,8 @@ export class ConfigurationManager implements IConfigurationManager { private toDispose: IDisposable[]; private _onDidSelectConfigurationName = new Emitter(); private providers: IDebugConfigurationProvider[]; + private debugAdapterProviders: Map; + constructor( @IWorkspaceContextService private contextService: IWorkspaceContextService, @@ -241,7 +243,7 @@ export class ConfigurationManager implements IConfigurationManager { @ILifecycleService lifecycleService: ILifecycleService ) { this.providers = []; - this.adapters = []; + this.debuggers = []; this.toDispose = []; this.registerListeners(lifecycleService); this.initLaunches(); @@ -250,6 +252,7 @@ export class ConfigurationManager implements IConfigurationManager { if (previousSelectedLaunch) { this.selectConfiguration(previousSelectedLaunch, this.storageService.get(DEBUG_SELECTED_CONFIG_NAME_KEY, StorageScope.WORKSPACE)); } + this.debugAdapterProviders = new Map(); } public registerDebugConfigurationProvider(handle: number, debugConfigurationProvider: IDebugConfigurationProvider): void { @@ -260,7 +263,7 @@ export class ConfigurationManager implements IConfigurationManager { debugConfigurationProvider.handle = handle; this.providers = this.providers.filter(p => p.handle !== handle); this.providers.push(debugConfigurationProvider); - const adapter = this.getAdapter(debugConfigurationProvider.type); + const adapter = this.getDebugger(debugConfigurationProvider.type); // Check if the provider contributes provideDebugConfigurations method if (adapter && debugConfigurationProvider.provideDebugConfigurations) { adapter.hasConfigurationProvider = true; @@ -300,12 +303,24 @@ export class ConfigurationManager implements IConfigurationManager { return TPromise.as(undefined); } + public registerDebugAdapterProvider(debugType: string, debugAdapterLauncher: IDebugAdapterProvider) { + this.debugAdapterProviders.set(debugType, debugAdapterLauncher); + } + + public createDebugAdapter(debugType: string, adapterExecutable: IAdapterExecutable): IDebugAdapter { + let dap = this.debugAdapterProviders.get(debugType); + if (!dap) { + dap = this.debugAdapterProviders.get('*'); + } + return dap.createDebugAdapter(debugType, adapterExecutable); + } + private registerListeners(lifecycleService: ILifecycleService): void { debuggersExtPoint.setHandler((extensions) => { extensions.forEach(extension => { extension.value.forEach(rawAdapter => { if (!rawAdapter.type || (typeof rawAdapter.type !== 'string')) { - extension.collector.error(nls.localize('debugNoType', "Debug adapter 'type' can not be omitted and must be of type 'string'.")); + extension.collector.error(nls.localize('debugNoType', "Debugger 'type' can not be omitted and must be of type 'string'.")); } if (rawAdapter.enableBreakpointsFor) { rawAdapter.enableBreakpointsFor.languageIds.forEach(modeId => { @@ -313,17 +328,17 @@ export class ConfigurationManager implements IConfigurationManager { }); } - const duplicate = this.adapters.filter(a => a.type === rawAdapter.type).pop(); + const duplicate = this.getDebugger(rawAdapter.type); if (duplicate) { duplicate.merge(rawAdapter, extension.description); } else { - this.adapters.push(new Adapter(this, rawAdapter, extension.description, this.configurationService, this.commandService)); + this.debuggers.push(new Debugger(this, rawAdapter, extension.description, this.configurationService, this.commandService)); } }); }); // update the schema to include all attributes, snippets and types from extensions. - this.adapters.forEach(adapter => { + this.debuggers.forEach(adapter => { const items = (schema.properties['configurations'].items); const schemaAttributes = adapter.getSchemaAttributes(); if (schemaAttributes) { @@ -448,24 +463,24 @@ export class ConfigurationManager implements IConfigurationManager { return this.breakpointModeIdsSet.has(modeId); } - public getAdapter(type: string): Adapter { - return this.adapters.filter(adapter => strings.equalsIgnoreCase(adapter.type, type)).pop(); + public getDebugger(type: string): Debugger { + return this.debuggers.filter(dbg => strings.equalsIgnoreCase(dbg.type, type)).pop(); } - public guessAdapter(type?: string): TPromise { + public guessDebugger(type?: string): TPromise { if (type) { - const adapter = this.getAdapter(type); + const adapter = this.getDebugger(type); return TPromise.as(adapter); } const editor = this.editorService.getActiveEditor(); - let candidates: Adapter[]; + let candidates: Debugger[]; if (editor) { const codeEditor = editor.getControl(); if (isCodeEditor(codeEditor)) { const model = codeEditor.getModel(); const language = model ? model.getLanguageIdentifier().language : undefined; - const adapters = this.adapters.filter(a => a.languages && a.languages.indexOf(language) >= 0); + const adapters = this.debuggers.filter(a => a.languages && a.languages.indexOf(language) >= 0); if (adapters.length === 1) { return TPromise.as(adapters[0]); } @@ -476,11 +491,11 @@ export class ConfigurationManager implements IConfigurationManager { } if (!candidates) { - candidates = this.adapters.filter(a => a.hasInitialConfiguration() || a.hasConfigurationProvider); + candidates = this.debuggers.filter(a => a.hasInitialConfiguration() || a.hasConfigurationProvider); } return this.quickOpenService.pick([...candidates, { label: 'More...', separator: { border: true } }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) .then(picked => { - if (picked instanceof Adapter) { + if (picked instanceof Debugger) { return picked; } if (picked) { @@ -600,7 +615,7 @@ class Launch implements ILaunch { result[key] = this.configurationResolverService.resolveAny(this.getWorkspaceForResolving(), result[key]); }); - const adapter = this.configurationManager.getAdapter(result.type); + const adapter = this.configurationManager.getDebugger(result.type); return this.configurationResolverService.resolveInteractiveVariables(result, adapter ? adapter.variables : null); } @@ -613,7 +628,7 @@ class Launch implements ILaunch { // launch.json not found: create one by collecting launch configs from debugConfigProviders - return this.configurationManager.guessAdapter(type).then(adapter => { + return this.configurationManager.guessDebugger(type).then(adapter => { if (adapter) { return this.configurationManager.provideDebugConfigurations(this.workspace.uri, adapter.type).then(initialConfigs => { return adapter.getInitialConfigurationContent(initialConfigs); diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 38a38972a81..8b5c9af6ba9 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -352,10 +352,10 @@ export class DebugService implements debug.IDebugService { const outputSeverity = event.body.category === 'stderr' ? severity.Error : event.body.category === 'console' ? severity.Warning : severity.Info; if (event.body.category === 'telemetry') { - // only log telemetry events from debug adapter if the adapter provided the telemetry key + // only log telemetry events from debug adapter if the debug extension provided the telemetry key // and the user opted in telemetry if (session.customTelemetryService && this.telemetryService.isOptedIn) { - // __GDPR__TODO__ We're sending events in the name of the debug adapter and we can not ensure that those are declared correctly. + // __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly. session.customTelemetryService.publicLog(event.body.output, event.body.data); } @@ -766,7 +766,7 @@ export class DebugService implements debug.IDebugService { config.noDebug = true; } - return (type ? TPromise.as(null) : this.configurationManager.guessAdapter().then(a => type = a && a.type)).then(() => + return (type ? TPromise.as(null) : this.configurationManager.guessDebugger().then(a => type = a && a.type)).then(() => (type ? this.extensionService.activateByEvent(`onDebugResolve:${type}`) : TPromise.as(null)).then(() => this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config).then(config => { // a falsy config indicates an aborted launch @@ -794,7 +794,7 @@ export class DebugService implements debug.IDebugService { return undefined; } - if (!this.configurationManager.getAdapter(resolvedConfig.type) || (config.request !== 'attach' && config.request !== 'launch')) { + if (!this.configurationManager.getDebugger(resolvedConfig.type) || (config.request !== 'attach' && config.request !== 'launch')) { let message: string; if (config.request !== 'attach' && config.request !== 'launch') { message = config.request ? nls.localize('debugRequestNotSupported', "Attribute '{0}' has an unsupported value '{1}' in the chosen debug configuration.", 'request', config.request) @@ -855,9 +855,9 @@ export class DebugService implements debug.IDebugService { telemetryInfo['common.vscodesessionid'] = info.sessionId; return telemetryInfo; }).then(data => { - const adapter = this.configurationManager.getAdapter(configuration.type); - const { aiKey, type } = adapter; - const publisher = adapter.extensionDescription.publisher; + const dbg = this.configurationManager.getDebugger(configuration.type); + const { aiKey, type } = dbg; + const publisher = dbg.extensionDescription.publisher; let client: TelemetryClient; let customTelemetryService: TelemetryService; @@ -882,7 +882,7 @@ export class DebugService implements debug.IDebugService { customTelemetryService = new TelemetryService({ appender }, this.configurationService); } - const session = this.instantiationService.createInstance(RawDebugSession, sessionId, configuration.debugServer, adapter, customTelemetryService, root); + const session = this.instantiationService.createInstance(RawDebugSession, sessionId, configuration.debugServer, dbg, customTelemetryService, root); const process = this.model.addProcess(configuration, session); this.allProcesses.set(process.getId(), process); @@ -946,8 +946,8 @@ export class DebugService implements debug.IDebugService { breakpointCount: this.model.getBreakpoints().length, exceptionBreakpoints: this.model.getExceptionBreakpoints(), watchExpressionsCount: this.model.getWatchExpressions().length, - extensionName: adapter.extensionDescription.id, - isBuiltin: adapter.extensionDescription.isBuiltin, + extensionName: dbg.extensionDescription.id, + isBuiltin: dbg.extensionDescription.isBuiltin, launchJsonExists: root && !!this.configurationService.getValue('launch', { resource: root.uri }) }); }).then(() => process, (error: Error | string) => { diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index 04f3a0dfe6e..86598c7d04f 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -4,27 +4,24 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import * as cp from 'child_process'; import * as net from 'net'; import { Event, Emitter } from 'vs/base/common/event'; -import * as platform from 'vs/base/common/platform'; import * as objects from 'vs/base/common/objects'; import { Action } from 'vs/base/common/actions'; import * as errors from 'vs/base/common/errors'; import { TPromise } from 'vs/base/common/winjs.base'; -import * as stdfork from 'vs/base/node/stdFork'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITerminalService } from 'vs/workbench/parts/terminal/common/terminal'; import { ITerminalService as IExternalTerminalService } from 'vs/workbench/parts/execution/common/execution'; import * as debug from 'vs/workbench/parts/debug/common/debug'; -import { Adapter } from 'vs/workbench/parts/debug/node/debugAdapter'; -import { V8Protocol } from 'vs/workbench/parts/debug/node/v8Protocol'; +import { Debugger } from 'vs/workbench/parts/debug/node/debugger'; import { IOutputService } from 'vs/workbench/parts/output/common/output'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { ExtensionsChannelId } from 'vs/platform/extensionManagement/common/extensionManagement'; import { TerminalSupport } from 'vs/workbench/parts/debug/electron-browser/terminalSupport'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { StreamDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; + export interface SessionExitedEvent extends debug.DebugEvent { body: { @@ -40,14 +37,46 @@ export interface SessionTerminatedEvent extends debug.DebugEvent { }; } -export class RawDebugSession extends V8Protocol implements debug.ISession { +export class SocketDebugAdapter extends StreamDebugAdapter { + + private socket: net.Socket; + + constructor(private host: string, private port: number) { + super(); + } + + startSession(): TPromise { + return new TPromise((c, e) => { + this.socket = net.createConnection(this.port, this.host, () => { + this.connect(this.socket, this.socket); + c(null); + }); + this.socket.on('error', (err: any) => { + e(err); + }); + this.socket.on('close', () => this._onExit.fire(0)); + }); + } + + stopSession(): TPromise { + if (this.socket !== null) { + this.socket.end(); + this.socket = undefined; + } + return void 0; + } +} + +export class RawDebugSession implements debug.ISession { + + private debugAdapter: debug.IDebugAdapter; public emittedStopped: boolean; public readyForBreakpoints: boolean; - private serverProcess: cp.ChildProcess; - private socket: net.Socket = null; - private cachedInitServer: TPromise; + //private serverProcess: cp.ChildProcess; + //private socket: net.Socket = null; + private cachedInitServerP: TPromise; private startTime: number; public disconnected: boolean; private sentPromises: TPromise[]; @@ -66,9 +95,9 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { private readonly _onDidEvent: Emitter; constructor( - id: string, + private id: string, private debugServerPort: number, - private adapter: Adapter, + private _debugger: Debugger, public customTelemetryService: ITelemetryService, public root: IWorkspaceFolder, @INotificationService private notificationService: INotificationService, @@ -78,7 +107,6 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { @IExternalTerminalService private nativeTerminalService: IExternalTerminalService, @IConfigurationService private configurationService: IConfigurationService ) { - super(id); this.emittedStopped = false; this.readyForBreakpoints = false; this.allThreadsContinued = true; @@ -96,6 +124,10 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { this._onDidEvent = new Emitter(); } + public getId(): string { + return this.id; + } + public get onDidInitialize(): Event { return this._onDidInitialize.event; } @@ -137,28 +169,49 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { } private initServer(): TPromise { - if (this.cachedInitServer) { - return this.cachedInitServer; + + if (this.cachedInitServerP) { + return this.cachedInitServerP; } - const serverPromise = this.debugServerPort ? this.connectServer(this.debugServerPort) : this.startServer(); - this.cachedInitServer = serverPromise.then(() => { + const startSessionP = this.startSession(); + + this.cachedInitServerP = startSessionP.then(() => { this.startTime = new Date().getTime(); }, err => { - this.cachedInitServer = null; + this.cachedInitServerP = null; return TPromise.wrapError(err); }); - return this.cachedInitServer; + return this.cachedInitServerP; + } + + private startSession(): TPromise { + + const debugAdapterP = this.debugServerPort + ? TPromise.as(new SocketDebugAdapter('127.0.0.1', this.debugServerPort)) + : this._debugger.createDebugAdapter(this.root, this.outputService); + + return debugAdapterP.then(debugAdapter => { + + this.debugAdapter = debugAdapter; + + this.debugAdapter.onError(err => this.onDapServerError(err)); + this.debugAdapter.onEvent(event => this.onDapEvent(event)); + this.debugAdapter.onRequest(request => this.dispatchRequest(request)); + this.debugAdapter.onExit(code => this.onServerExit()); + + return this.debugAdapter.startSession(); + }); } public custom(request: string, args: any): TPromise { return this.send(request, args); } - protected send(command: string, args: any, cancelOnDisconnect = true): TPromise { + private send(command: string, args: any, cancelOnDisconnect = true): TPromise { return this.initServer().then(() => { - const promise = super.send(command, args).then(response => response, (errorResponse: DebugProtocol.ErrorResponse) => { + const promise = this.internalSend(command, args).then(response => response, (errorResponse: DebugProtocol.ErrorResponse) => { const error = errorResponse && errorResponse.body ? errorResponse.body.error : null; const errorMessage = errorResponse ? errorResponse.message : ''; const telemetryMessage = error ? debug.formatPII(error.format, true, error.variables) : errorMessage; @@ -199,8 +252,22 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { }); } - protected onEvent(event: debug.DebugEvent): void { - event.sessionId = this.getId(); + private internalSend(command: string, args: any): TPromise { + let errorCallback: (error: Error) => void; + return new TPromise((completeDispatch, errorDispatch) => { + errorCallback = errorDispatch; + this.debugAdapter.sendRequest(command, args, (result: R) => { + if (result.success) { + completeDispatch(result); + } else { + errorDispatch(result); + } + }); + }, () => errorCallback(errors.canceled())); + } + + private onDapEvent(event: debug.DebugEvent): void { + event.sessionId = this.id; if (event.event === 'initialized') { this.readyForBreakpoints = true; @@ -317,7 +384,7 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { this.sentPromises = []; }, 1000); - if ((this.serverProcess || this.socket) && !this.disconnected) { + if (this.debugAdapter && !this.disconnected) { // point of no return: from now on don't report any errors this.disconnected = true; return this.send('disconnect', { restart: restart }, false).then(() => this.stopServer(), () => this.stopServer()); @@ -392,16 +459,24 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { return (new Date().getTime() - this.startTime) / 1000; } - protected dispatchRequest(request: DebugProtocol.Request, response: DebugProtocol.Response): void { + private dispatchRequest(request: DebugProtocol.Request): void { + + const response: DebugProtocol.Response = { + type: 'response', + seq: 0, + command: request.command, + request_seq: request.seq, + success: true + }; if (request.command === 'runInTerminal') { TerminalSupport.runInTerminal(this.terminalService, this.nativeTerminalService, this.configurationService, request.arguments, response).then(() => { - this.sendResponse(response); + this.debugAdapter.sendResponse(response); }, e => { response.success = false; response.message = e.message; - this.sendResponse(response); + this.debugAdapter.sendResponse(response); }); } else if (request.command === 'handshake') { try { @@ -411,16 +486,16 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { response.body = { signature: sig }; - this.sendResponse(response); + this.debugAdapter.sendResponse(response); } catch (e) { response.success = false; response.message = e.message; - this.sendResponse(response); + this.debugAdapter.sendResponse(response); } } else { response.success = false; response.message = `unknown request '${request.command}'`; - this.sendResponse(response); + this.debugAdapter.sendResponse(response); } } @@ -436,111 +511,36 @@ export class RawDebugSession extends V8Protocol implements debug.ISession { }); } - private connectServer(port: number): TPromise { - return new TPromise((c, e) => { - this.socket = net.createConnection(port, '127.0.0.1', () => { - this.connect(this.socket, this.socket); - c(null); - }); - this.socket.on('error', (err: any) => { - e(err); - }); - this.socket.on('close', () => this.onServerExit()); - }); - } - - private startServer(): TPromise { - return this.adapter.getAdapterExecutable(this.root).then(ae => this.launchServer(ae).then(() => { - this.serverProcess.on('error', (err: Error) => this.onServerError(err)); - this.serverProcess.on('exit', (code: number, signal: string) => this.onServerExit()); - - const sanitize = (s: string) => s.toString().replace(/\r?\n$/mg, ''); - // this.serverProcess.stdout.on('data', (data: string) => { - // console.log('%c' + sanitize(data), 'background: #ddd; font-style: italic;'); - // }); - this.serverProcess.stderr.on('data', (data: string) => { - this.outputService.getChannel(ExtensionsChannelId).append(sanitize(data)); - }); - - this.connect(this.serverProcess.stdout, this.serverProcess.stdin); - })); - } - - private launchServer(launch: debug.IAdapterExecutable): TPromise { - return new TPromise((c, e) => { - if (launch.command === 'node') { - if (Array.isArray(launch.args) && launch.args.length > 0) { - stdfork.fork(launch.args[0], launch.args.slice(1), {}, (err, child) => { - if (err) { - e(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", launch.args[0]))); - } - this.serverProcess = child; - c(null); - }); - } else { - e(new Error(nls.localize('unableToLaunchDebugAdapterNoArgs', "Unable to launch debug adapter."))); - } - } else { - this.serverProcess = cp.spawn(launch.command, launch.args, { - stdio: [ - 'pipe', // stdin - 'pipe', // stdout - 'pipe' // stderr - ], - }); - c(null); - } - }); - } - private stopServer(): TPromise { - if (this.socket !== null) { - this.socket.end(); - this.cachedInitServer = null; + if (/* this.socket !== null */ this.debugAdapter instanceof SocketDebugAdapter) { + this.debugAdapter.stopSession(); + this.cachedInitServerP = null; } - this.onEvent({ event: 'exit', type: 'event', seq: 0 }); - if (!this.serverProcess) { + this.onDapEvent({ event: 'exit', type: 'event', seq: 0 }); + if (/* !this.serverProcess */ this.debugAdapter instanceof SocketDebugAdapter) { return TPromise.as(null); } this.disconnected = true; - let ret: TPromise; - // when killing a process in windows its child - // processes are *not* killed but become root - // processes. Therefore we use TASKKILL.EXE - if (platform.isWindows) { - ret = new TPromise((c, e) => { - const killer = cp.exec(`taskkill /F /T /PID ${this.serverProcess.pid}`, function (err, stdout, stderr) { - if (err) { - return e(err); - } - }); - killer.on('exit', c); - killer.on('error', e); - }); - } else { - this.serverProcess.kill('SIGTERM'); - ret = TPromise.as(null); - } - - return ret; + return this.debugAdapter.stopSession(); } - protected onServerError(err: Error): void { - this.notificationService.error(nls.localize('stoppingDebugAdapter', "{0}. Stopping the debug adapter.", err.message)); + private onDapServerError(err: Error): void { + this.notificationService.error(err.message || err.toString()); this.stopServer().done(null, errors.onUnexpectedError); } private onServerExit(): void { - this.serverProcess = null; - this.cachedInitServer = null; + //this.serverProcess = null; + this.debugAdapter = null; + this.cachedInitServerP = null; if (!this.disconnected) { this.notificationService.error(nls.localize('debugAdapterCrash', "Debug adapter process has terminated unexpectedly")); } - this.onEvent({ event: 'exit', type: 'event', seq: 0 }); + this.onDapEvent({ event: 'exit', type: 'event', seq: 0 }); } public dispose(): void { diff --git a/src/vs/workbench/parts/debug/node/debugAdapter.ts b/src/vs/workbench/parts/debug/node/debugAdapter.ts index fc2f741c812..afcb5eb7d9e 100644 --- a/src/vs/workbench/parts/debug/node/debugAdapter.ts +++ b/src/vs/workbench/parts/debug/node/debugAdapter.ts @@ -4,263 +4,486 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; -import * as path from 'path'; +import * as cp from 'child_process'; +import * as stream from 'stream'; import * as nls from 'vs/nls'; -import { TPromise } from 'vs/base/common/winjs.base'; +import * as paths from 'vs/base/common/paths'; import * as strings from 'vs/base/common/strings'; import * as objects from 'vs/base/common/objects'; -import * as paths from 'vs/base/common/paths'; import * as platform from 'vs/base/common/platform'; -import { IJSONSchema, IJSONSchemaSnippet } from 'vs/base/common/jsonSchema'; -import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { IConfig, IRawAdapter, IAdapterExecutable, INTERNAL_CONSOLE_OPTIONS_SCHEMA, IConfigurationManager } from 'vs/workbench/parts/debug/common/debug'; +import * as stdfork from 'vs/base/node/stdFork'; +import { Emitter, Event } from 'vs/base/common/event'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { ExtensionsChannelId } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ICommandService } from 'vs/platform/commands/common/commands'; +import * as debug from 'vs/workbench/parts/debug/common/debug'; +import { IOutputService } from 'vs/workbench/parts/output/common/output'; -export class Adapter { +/** + * Abstract implementation of the low level API for a debug adapter. + * Missing is how this API communicates with the debug adapter. + */ +export abstract class AbstractDebugAdapter implements debug.IDebugAdapter { - constructor(private configurationManager: IConfigurationManager, private rawAdapter: IRawAdapter, public extensionDescription: IExtensionDescription, - @IConfigurationService private configurationService: IConfigurationService, - @ICommandService private commandService: ICommandService - ) { - if (rawAdapter.windows) { - rawAdapter.win = rawAdapter.windows; + private sequence: number; + private pendingRequests: Map void>; + private requestCallback: (request: DebugProtocol.Request) => void; + private eventCallback: (request: DebugProtocol.Event) => void; + + protected readonly _onError: Emitter; + protected readonly _onExit: Emitter; + + constructor() { + this.sequence = 1; + this.pendingRequests = new Map void>(); + + this._onError = new Emitter(); + this._onExit = new Emitter(); + } + + abstract startSession(): TPromise; + abstract stopSession(): TPromise; + + public dispose(): void { + } + + abstract sendMessage(message: DebugProtocol.ProtocolMessage): void; + + public get onError(): Event { + return this._onError.event; + } + + public get onExit(): Event { + return this._onExit.event; + } + + public onEvent(callback: (event: DebugProtocol.Event) => void) { + if (this.eventCallback) { + this._onError.fire(new Error(`attempt to set more than one 'Event' callback`)); + } + this.eventCallback = callback; + } + + public onRequest(callback: (request: DebugProtocol.Request) => void) { + if (this.requestCallback) { + this._onError.fire(new Error(`attempt to set more than one 'Request' callback`)); + } + this.requestCallback = callback; + } + + public sendResponse(response: DebugProtocol.Response): void { + if (response.seq > 0) { + this._onError.fire(new Error(`attempt to send more than one response for command ${response.command}`)); + } else { + this.internalSend('response', response); } } - public hasConfigurationProvider = false; + public sendRequest(command: string, args: any, clb: (result: DebugProtocol.Response) => void): void { - public getAdapterExecutable(root: IWorkspaceFolder, verifyAgainstFS = true): TPromise { + const request: any = { + command: command + }; + if (args && Object.keys(args).length > 0) { + request.arguments = args; + } - return this.configurationManager.debugAdapterExecutable(root ? root.uri : undefined, this.rawAdapter.type).then(adapterExecutable => { + this.internalSend('request', request); - if (adapterExecutable) { - return this.verifyAdapterDetails(adapterExecutable, verifyAgainstFS); - } - - // try deprecated command based extension API - if (this.rawAdapter.adapterExecutableCommand) { - return this.commandService.executeCommand(this.rawAdapter.adapterExecutableCommand, root ? root.uri.toString() : undefined).then(ad => { - return this.verifyAdapterDetails(ad, verifyAgainstFS); - }); - } - - // fallback: executable contribution specified in package.json - adapterExecutable = { - command: this.getProgram(), - args: this.getAttributeBasedOnPlatform('args') - }; - const runtime = this.getRuntime(); - if (runtime) { - const runtimeArgs = this.getAttributeBasedOnPlatform('runtimeArgs'); - adapterExecutable.args = (runtimeArgs || []).concat([adapterExecutable.command]).concat(adapterExecutable.args || []); - adapterExecutable.command = runtime; - } - return this.verifyAdapterDetails(adapterExecutable, verifyAgainstFS); - }); + if (clb) { + // store callback for this request + this.pendingRequests.set(request.seq, clb); + } } - private verifyAdapterDetails(details: IAdapterExecutable, verifyAgainstFS: boolean): TPromise { + public acceptMessage(message: DebugProtocol.ProtocolMessage) { + switch (message.type) { + case 'event': + if (this.eventCallback) { + this.eventCallback(message); + } + break; + case 'request': + if (this.requestCallback) { + this.requestCallback(message); + } + break; + case 'response': + const response = message; + const clb = this.pendingRequests.get(response.request_seq); + if (clb) { + this.pendingRequests.delete(response.request_seq); + clb(response); + } + break; + } + } - if (details.command) { - if (verifyAgainstFS) { - if (path.isAbsolute(details.command)) { - return new TPromise((c, e) => { - fs.exists(details.command, exists => { - if (exists) { - c(details); - } else { - e(new Error(nls.localize('debugAdapterBinNotFound', "Debug adapter executable '{0}' does not exist.", details.command))); - } - }); - }); + private internalSend(typ: 'request' | 'response' | 'event', message: DebugProtocol.ProtocolMessage): void { + + message.type = typ; + message.seq = this.sequence++; + + this.sendMessage(message); + } +} + +/** + * An implementation that communicates via two streams with the debug adapter. + */ +export abstract class StreamDebugAdapter extends AbstractDebugAdapter { + + private static readonly TWO_CRLF = '\r\n\r\n'; + + private outputStream: stream.Writable; + private rawData: Buffer; + private contentLength: number; + + constructor() { + super(); + } + + public connect(readable: stream.Readable, writable: stream.Writable): void { + + this.outputStream = writable; + this.rawData = Buffer.allocUnsafe(0); + this.contentLength = -1; + + readable.on('data', (data: Buffer) => this.handleData(data)); + + // readable.on('close', () => { + // this._emitEvent(new Event('close')); + // }); + // readable.on('error', (error) => { + // this._emitEvent(new Event('error', 'readable error: ' + (error && error.message))); + // }); + + // writable.on('error', (error) => { + // this._emitEvent(new Event('error', 'writable error: ' + (error && error.message))); + // }); + } + + public sendMessage(message: DebugProtocol.ProtocolMessage): void { + + if (this.outputStream) { + const json = JSON.stringify(message); + this.outputStream.write(`Content-Length: ${Buffer.byteLength(json, 'utf8')}${StreamDebugAdapter.TWO_CRLF}${json}`, 'utf8'); + } + } + + private handleData(data: Buffer): void { + + this.rawData = Buffer.concat([this.rawData, data]); + + while (true) { + if (this.contentLength >= 0) { + if (this.rawData.length >= this.contentLength) { + const message = this.rawData.toString('utf8', 0, this.contentLength); + this.rawData = this.rawData.slice(this.contentLength); + this.contentLength = -1; + if (message.length > 0) { + try { + this.acceptMessage(JSON.parse(message)); + } catch (e) { + this._onError.fire(new Error((e.message || e) + '\n' + message)); + } + } + continue; // there may be more complete messages to process + } + } else { + const idx = this.rawData.indexOf(StreamDebugAdapter.TWO_CRLF); + if (idx !== -1) { + const header = this.rawData.toString('utf8', 0, idx); + const lines = header.split('\r\n'); + for (const h of lines) { + const kvPair = h.split(/: +/); + if (kvPair[0] === 'Content-Length') { + this.contentLength = Number(kvPair[1]); + } + } + this.rawData = this.rawData.slice(idx + StreamDebugAdapter.TWO_CRLF.length); + continue; + } + } + break; + } + } +} + +/** + * An implementation that launches the debug adapter as a separate process and communicates via stdin/stdout. +*/ +export class DebugAdapter extends StreamDebugAdapter { + + private _serverProcess: cp.ChildProcess; + + constructor(private _debugType: string, private _adapterExecutable: debug.IAdapterExecutable | null, extensionDescriptions: IExtensionDescription[], private _outputService?: IOutputService) { + super(); + + if (!this._adapterExecutable) { + this._adapterExecutable = DebugAdapter.platformAdapterExecutable(extensionDescriptions, this._debugType); + } + } + + startSession(): TPromise { + + return new TPromise((c, e) => { + + // verify executables + if (this._adapterExecutable.command) { + if (paths.isAbsolute(this._adapterExecutable.command)) { + if (!fs.existsSync(this._adapterExecutable.command)) { + e(new Error(nls.localize('debugAdapterBinNotFound', "Debug adapter executable '{0}' does not exist.", this._adapterExecutable.command))); + } } else { // relative path - if (details.command.indexOf('/') < 0 && details.command.indexOf('\\') < 0) { + if (this._adapterExecutable.command.indexOf('/') < 0 && this._adapterExecutable.command.indexOf('\\') < 0) { // no separators: command looks like a runtime name like 'node' or 'mono' - return TPromise.as(details); // TODO: check that the runtime is available on PATH + // TODO: check that the runtime is available on PATH } } } else { - return TPromise.as(details); + e(new Error(nls.localize({ key: 'debugAdapterCannotDetermineExecutable', comment: ['Adapter executable file not found'] }, + "Cannot determine executable for debug adapter '{0}'.", this._debugType))); } - } - return TPromise.wrapError(new Error(nls.localize({ key: 'debugAdapterCannotDetermineExecutable', comment: ['Adapter executable file not found'] }, - "Cannot determine executable for debug adapter '{0}'.", this.type))); - } - - private getRuntime(): string { - let runtime = this.getAttributeBasedOnPlatform('runtime'); - if (runtime && runtime.indexOf('./') === 0) { - runtime = paths.join(this.extensionDescription.extensionFolderPath, runtime); - } - return runtime; - } - - private getProgram(): string { - let program = this.getAttributeBasedOnPlatform('program'); - if (program) { - program = paths.join(this.extensionDescription.extensionFolderPath, program); - } - return program; - } - - public get aiKey(): string { - return this.rawAdapter.aiKey; - } - - public get label(): string { - return this.rawAdapter.label || this.rawAdapter.type; - } - - public get type(): string { - return this.rawAdapter.type; - } - - public get variables(): { [key: string]: string } { - return this.rawAdapter.variables; - } - - public get configurationSnippets(): IJSONSchemaSnippet[] { - return this.rawAdapter.configurationSnippets; - } - - public get languages(): string[] { - return this.rawAdapter.languages; - } - - public merge(secondRawAdapter: IRawAdapter, extensionDescription: IExtensionDescription): void { - // Give priority to built in debug adapters - if (extensionDescription.isBuiltin) { - this.extensionDescription = extensionDescription; - } - objects.mixin(this.rawAdapter, secondRawAdapter, extensionDescription.isBuiltin); - } - - public hasInitialConfiguration(): boolean { - return !!this.rawAdapter.initialConfigurations; - } - - public getInitialConfigurationContent(initialConfigs?: IConfig[]): TPromise { - // at this point we got some configs from the package.json and/or from registered DebugConfigurationProviders - let initialConfigurations = this.rawAdapter.initialConfigurations || []; - if (initialConfigs) { - initialConfigurations = initialConfigurations.concat(initialConfigs); - } - - const configs = JSON.stringify(initialConfigurations, null, '\t').split('\n').map(line => '\t' + line).join('\n').trim(); - const comment1 = nls.localize('launch.config.comment1', "Use IntelliSense to learn about possible attributes."); - const comment2 = nls.localize('launch.config.comment2', "Hover to view descriptions of existing attributes."); - const comment3 = nls.localize('launch.config.comment3', "For more information, visit: {0}", 'https://go.microsoft.com/fwlink/?linkid=830387'); - - let content = [ - '{', - `\t// ${comment1}`, - `\t// ${comment2}`, - `\t// ${comment3}`, - `\t"version": "0.2.0",`, - `\t"configurations": ${configs}`, - '}' - ].join('\n'); - - // fix formatting - const editorConfig = this.configurationService.getValue(); - if (editorConfig.editor && editorConfig.editor.insertSpaces) { - content = content.replace(new RegExp('\t', 'g'), strings.repeat(' ', editorConfig.editor.tabSize)); - } - - return TPromise.as(content); - } - - public getSchemaAttributes(): IJSONSchema[] { - if (!this.rawAdapter.configurationAttributes) { - return null; - } - // fill in the default configuration attributes shared by all adapters. - return Object.keys(this.rawAdapter.configurationAttributes).map(request => { - const attributes: IJSONSchema = this.rawAdapter.configurationAttributes[request]; - const defaultRequired = ['name', 'type', 'request']; - attributes.required = attributes.required && attributes.required.length ? defaultRequired.concat(attributes.required) : defaultRequired; - attributes.additionalProperties = false; - attributes.type = 'object'; - if (!attributes.properties) { - attributes.properties = {}; + if (this._adapterExecutable.command === 'node' /*&& this.outputService*/) { + if (Array.isArray(this._adapterExecutable.args) && this._adapterExecutable.args.length > 0) { + stdfork.fork(this._adapterExecutable.args[0], this._adapterExecutable.args.slice(1), {}, (err, child) => { + if (err) { + e(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", this._adapterExecutable.args[0]))); + } + this._serverProcess = child; + c(null); + }); + } else { + e(new Error(nls.localize('unableToLaunchDebugAdapterNoArgs', "Unable to launch debug adapter."))); + } + } else { + this._serverProcess = cp.spawn(this._adapterExecutable.command, this._adapterExecutable.args); + c(null); } - const properties = attributes.properties; - properties['type'] = { - enum: [this.type], - description: nls.localize('debugType', "Type of configuration."), - pattern: '^(?!node2)', - errorMessage: nls.localize('debugTypeNotRecognised', "The debug type is not recognized. Make sure that you have a corresponding debug extension installed and that it is enabled."), - patternErrorMessage: nls.localize('node2NotSupported', "\"node2\" is no longer supported, use \"node\" instead and set the \"protocol\" attribute to \"inspector\".") - }; - properties['name'] = { - type: 'string', - description: nls.localize('debugName', "Name of configuration; appears in the launch configuration drop down menu."), - default: 'Launch' - }; - properties['request'] = { - enum: [request], - description: nls.localize('debugRequest', "Request type of configuration. Can be \"launch\" or \"attach\"."), - }; - properties['debugServer'] = { - type: 'number', - description: nls.localize('debugServer', "For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode"), - default: 4711 - }; - properties['preLaunchTask'] = { - type: ['string', 'null'], - default: '', - description: nls.localize('debugPrelaunchTask', "Task to run before debug session starts.") - }; - properties['postDebugTask'] = { - type: ['string', 'null'], - default: '', - description: nls.localize('debugPostDebugTask', "Task to run after debug session ends.") - }; - properties['internalConsoleOptions'] = INTERNAL_CONSOLE_OPTIONS_SCHEMA; + }).then(_ => { + this._serverProcess.on('error', (err: Error) => this._onError.fire(err)); + this._serverProcess.on('exit', (code: number, signal: string) => this._onExit.fire(code)); - const osProperties = objects.deepClone(properties); - properties['windows'] = { - type: 'object', - description: nls.localize('debugWindowsConfiguration', "Windows specific launch configuration attributes."), - properties: osProperties - }; - properties['osx'] = { - type: 'object', - description: nls.localize('debugOSXConfiguration', "OS X specific launch configuration attributes."), - properties: osProperties - }; - properties['linux'] = { - type: 'object', - description: nls.localize('debugLinuxConfiguration', "Linux specific launch configuration attributes."), - properties: osProperties - }; - Object.keys(attributes.properties).forEach(name => { - // Use schema allOf property to get independent error reporting #21113 - attributes.properties[name].pattern = attributes.properties[name].pattern || '^(?!.*\\$\\{(env|config|command)\\.)'; - attributes.properties[name].patternErrorMessage = attributes.properties[name].patternErrorMessage || - nls.localize('deprecatedVariables', "'env.', 'config.' and 'command.' are deprecated, use 'env:', 'config:' and 'command:' instead."); - }); + if (this._outputService) { + const sanitize = (s: string) => s.toString().replace(/\r?\n$/mg, ''); + // this.serverProcess.stdout.on('data', (data: string) => { + // console.log('%c' + sanitize(data), 'background: #ddd; font-style: italic;'); + // }); + this._serverProcess.stderr.on('data', (data: string) => { + this._outputService.getChannel(ExtensionsChannelId).append(sanitize(data)); + }); + } - return attributes; + this.connect(this._serverProcess.stdout, this._serverProcess.stdin); + }, err => { + this._onError.fire(err); }); } - private getAttributeBasedOnPlatform(key: string): any { - let result: any; - if (platform.isWindows && !process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432') && this.rawAdapter.winx86) { - result = this.rawAdapter.winx86[key]; - } else if (platform.isWindows && this.rawAdapter.win) { - result = this.rawAdapter.win[key]; - } else if (platform.isMacintosh && this.rawAdapter.osx) { - result = this.rawAdapter.osx[key]; - } else if (platform.isLinux && this.rawAdapter.linux) { - result = this.rawAdapter.linux[key]; + stopSession(): TPromise { + + // when killing a process in windows its child + // processes are *not* killed but become root + // processes. Therefore we use TASKKILL.EXE + if (platform.isWindows) { + return new TPromise((c, e) => { + const killer = cp.exec(`taskkill /F /T /PID ${this._serverProcess.pid}`, function (err, stdout, stderr) { + if (err) { + return e(err); + } + }); + killer.on('exit', c); + killer.on('error', e); + }); + } else { + this._serverProcess.kill('SIGTERM'); + return TPromise.as(null); + } + } + + private static extract(dbg: debug.IRawAdapter, extensionFolderPath: string) { + if (!dbg) { + return undefined; + } + let x: debug.IRawAdapter = {}; + + if (dbg.runtime) { + if (dbg.runtime.indexOf('./') === 0) { // TODO + x.runtime = paths.join(extensionFolderPath, dbg.runtime); + } else { + x.runtime = dbg.runtime; + } + } + if (dbg.runtimeArgs) { + x.runtimeArgs = dbg.runtimeArgs; + } + if (dbg.program) { + if (!paths.isAbsolute(dbg.program)) { + x.program = paths.join(extensionFolderPath, dbg.program); + } else { + x.program = dbg.program; + } + } + if (dbg.args) { + x.args = dbg.args; } - return result || this.rawAdapter[key]; + if (dbg.win) { + x.win = DebugAdapter.extract(dbg.win, extensionFolderPath); + } + if (dbg.winx86) { + x.winx86 = DebugAdapter.extract(dbg.winx86, extensionFolderPath); + } + if (dbg.windows) { + x.windows = DebugAdapter.extract(dbg.windows, extensionFolderPath); + } + if (dbg.osx) { + x.osx = DebugAdapter.extract(dbg.osx, extensionFolderPath); + } + if (dbg.linux) { + x.linux = DebugAdapter.extract(dbg.linux, extensionFolderPath); + } + return x; + } + + static platformAdapterExecutable(extensionDescriptions: IExtensionDescription[], debugType: string): debug.IAdapterExecutable { + + let result: debug.IRawAdapter = {}; + + debugType = debugType.toLowerCase(); + + // merge all contributions into one + for (const ed of extensionDescriptions) { + if (ed.contributes) { + const debuggers = ed.contributes['debuggers']; + if (debuggers && debuggers.length > 0) { + const dbgs = debuggers.filter(d => strings.equalsIgnoreCase(d.type, debugType)); + for (const dbg of dbgs) { + + // extract relevant attributes and make then absolute where needed + const dbg1 = DebugAdapter.extract(dbg, ed.extensionFolderPath); + + // merge + objects.mixin(result, dbg1, ed.isBuiltin); + } + } + } + } + + // select the right platform + let platformInfo: debug.IRawEnvAdapter; + if (platform.isWindows && !process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432')) { + platformInfo = result.winx86 || result.win || result.windows; + } else if (platform.isWindows) { + platformInfo = result.win || result.windows; + } else if (platform.isMacintosh) { + platformInfo = result.osx; + } else if (platform.isLinux) { + platformInfo = result.linux; + } + platformInfo = platformInfo || result; + + // these are the relevant attributes + let program = platformInfo.program || result.program; + const args = platformInfo.args || result.args; + let runtime = platformInfo.runtime || result.runtime; + const runtimeArgs = platformInfo.runtimeArgs || result.runtimeArgs; + + if (runtime) { + return { + command: runtime, + args: (runtimeArgs || []).concat([program]).concat(args || []) + }; + } else { + return { + command: program, + args: args || [] + }; + } + } +} + +// path hooks helpers + +export function convertToDAPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (source: DebugProtocol.Source) => void) { + convertPaths(msg, (toDA: boolean, source: DebugProtocol.Source | undefined) => { + if (toDA && source) { + fixSourcePaths(source); + } + }); +} + +export function convertToVSCPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (source: DebugProtocol.Source) => void) { + convertPaths(msg, (toDA: boolean, source: DebugProtocol.Source | undefined) => { + if (!toDA && source) { + fixSourcePaths(source); + } + }); +} + +function convertPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (toDA: boolean, source: DebugProtocol.Source | undefined) => void) { + switch (msg.type) { + case 'event': + const event = msg; + switch (event.event) { + case 'output': + fixSourcePaths(false, (event).body.source); + break; + case 'loadedSource': + fixSourcePaths(false, (event).body.source); + break; + case 'breakpoint': + fixSourcePaths(false, (event).body.breakpoint.source); + break; + default: + break; + } + break; + case 'request': + const request = msg; + switch (request.command) { + case 'setBreakpoints': + fixSourcePaths(true, (request.arguments).source); + break; + case 'source': + fixSourcePaths(true, (request.arguments).source); + break; + case 'gotoTargets': + fixSourcePaths(true, (request.arguments).source); + break; + default: + break; + } + break; + case 'response': + const response = msg; + switch (response.command) { + case 'stackTrace': + const r1 = response; + r1.body.stackFrames.forEach(frame => fixSourcePaths(false, frame.source)); + break; + case 'loadedSources': + const r2 = response; + r2.body.sources.forEach(source => fixSourcePaths(false, source)); + break; + case 'scopes': + const r3 = response; + r3.body.scopes.forEach(scope => fixSourcePaths(false, scope.source)); + break; + case 'setFunctionBreakpoints': + const r4 = response; + r4.body.breakpoints.forEach(bp => fixSourcePaths(false, bp.source)); + break; + case 'setBreakpoints': + const r5 = response; + r5.body.breakpoints.forEach(bp => fixSourcePaths(false, bp.source)); + break; + default: + break; + } + break; } } diff --git a/src/vs/workbench/parts/debug/node/debugger.ts b/src/vs/workbench/parts/debug/node/debugger.ts new file mode 100644 index 00000000000..e9e08f8fc2e --- /dev/null +++ b/src/vs/workbench/parts/debug/node/debugger.ts @@ -0,0 +1,206 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { TPromise } from 'vs/base/common/winjs.base'; +import * as strings from 'vs/base/common/strings'; +import * as objects from 'vs/base/common/objects'; +import { IJSONSchema, IJSONSchemaSnippet } from 'vs/base/common/jsonSchema'; +import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IConfig, IRawAdapter, IAdapterExecutable, INTERNAL_CONSOLE_OPTIONS_SCHEMA, IConfigurationManager, IDebugAdapter, IDebugConfiguration } from 'vs/workbench/parts/debug/common/debug'; +import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { IOutputService } from 'vs/workbench/parts/output/common/output'; +import { DebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; + + +export class Debugger { + + private _mergedExtensionDescriptions: IExtensionDescription[]; + + constructor(private configurationManager: IConfigurationManager, private rawAdapter: IRawAdapter, public extensionDescription: IExtensionDescription, + @IConfigurationService private configurationService: IConfigurationService, + @ICommandService private commandService: ICommandService + ) { + this._mergedExtensionDescriptions = [extensionDescription]; + } + + public hasConfigurationProvider = false; + + public createDebugAdapter(root: IWorkspaceFolder, outputService: IOutputService): TPromise { + return this.getAdapterExecutable(root).then(adapterExecutable => { + const debugConfigs = this.configurationService.getValue('debug'); + if (debugConfigs.extensionHostDebugAdapter) { + return this.configurationManager.createDebugAdapter(this.rawAdapter.type, adapterExecutable); + } else { + return new DebugAdapter(this.rawAdapter.type, adapterExecutable, this._mergedExtensionDescriptions, outputService); + } + }); + } + + public getAdapterExecutable(root: IWorkspaceFolder): TPromise { + + return this.configurationManager.debugAdapterExecutable(root ? root.uri : undefined, this.rawAdapter.type).then(adapterExecutable => { + + if (adapterExecutable) { + return adapterExecutable; + } + + // try deprecated command based extension API + if (this.rawAdapter.adapterExecutableCommand) { + return this.commandService.executeCommand(this.rawAdapter.adapterExecutableCommand, root ? root.uri.toString() : undefined); + } + + return TPromise.as(null); + }); + } + + public get aiKey(): string { + return this.rawAdapter.aiKey; + } + + public get label(): string { + return this.rawAdapter.label || this.rawAdapter.type; + } + + public get type(): string { + return this.rawAdapter.type; + } + + public get variables(): { [key: string]: string } { + return this.rawAdapter.variables; + } + + public get configurationSnippets(): IJSONSchemaSnippet[] { + return this.rawAdapter.configurationSnippets; + } + + public get languages(): string[] { + return this.rawAdapter.languages; + } + + public merge(secondRawAdapter: IRawAdapter, extensionDescription: IExtensionDescription): void { + + // remember all ext descriptions that are the source of this debugger + this._mergedExtensionDescriptions.push(extensionDescription); + + // Give priority to built in debug adapters + if (extensionDescription.isBuiltin) { + this.extensionDescription = extensionDescription; + } + objects.mixin(this.rawAdapter, secondRawAdapter, extensionDescription.isBuiltin); + } + + public hasInitialConfiguration(): boolean { + return !!this.rawAdapter.initialConfigurations; + } + + public getInitialConfigurationContent(initialConfigs?: IConfig[]): TPromise { + // at this point we got some configs from the package.json and/or from registered DebugConfigurationProviders + let initialConfigurations = this.rawAdapter.initialConfigurations || []; + if (initialConfigs) { + initialConfigurations = initialConfigurations.concat(initialConfigs); + } + + const configs = JSON.stringify(initialConfigurations, null, '\t').split('\n').map(line => '\t' + line).join('\n').trim(); + const comment1 = nls.localize('launch.config.comment1', "Use IntelliSense to learn about possible attributes."); + const comment2 = nls.localize('launch.config.comment2', "Hover to view descriptions of existing attributes."); + const comment3 = nls.localize('launch.config.comment3', "For more information, visit: {0}", 'https://go.microsoft.com/fwlink/?linkid=830387'); + + let content = [ + '{', + `\t// ${comment1}`, + `\t// ${comment2}`, + `\t// ${comment3}`, + `\t"version": "0.2.0",`, + `\t"configurations": ${configs}`, + '}' + ].join('\n'); + + // fix formatting + const editorConfig = this.configurationService.getValue(); + if (editorConfig.editor && editorConfig.editor.insertSpaces) { + content = content.replace(new RegExp('\t', 'g'), strings.repeat(' ', editorConfig.editor.tabSize)); + } + + return TPromise.as(content); + } + + public getSchemaAttributes(): IJSONSchema[] { + if (!this.rawAdapter.configurationAttributes) { + return null; + } + // fill in the default configuration attributes shared by all adapters. + return Object.keys(this.rawAdapter.configurationAttributes).map(request => { + const attributes: IJSONSchema = this.rawAdapter.configurationAttributes[request]; + const defaultRequired = ['name', 'type', 'request']; + attributes.required = attributes.required && attributes.required.length ? defaultRequired.concat(attributes.required) : defaultRequired; + attributes.additionalProperties = false; + attributes.type = 'object'; + if (!attributes.properties) { + attributes.properties = {}; + } + const properties = attributes.properties; + properties['type'] = { + enum: [this.type], + description: nls.localize('debugType', "Type of configuration."), + pattern: '^(?!node2)', + errorMessage: nls.localize('debugTypeNotRecognised', "The debug type is not recognized. Make sure that you have a corresponding debug extension installed and that it is enabled."), + patternErrorMessage: nls.localize('node2NotSupported', "\"node2\" is no longer supported, use \"node\" instead and set the \"protocol\" attribute to \"inspector\".") + }; + properties['name'] = { + type: 'string', + description: nls.localize('debugName', "Name of configuration; appears in the launch configuration drop down menu."), + default: 'Launch' + }; + properties['request'] = { + enum: [request], + description: nls.localize('debugRequest', "Request type of configuration. Can be \"launch\" or \"attach\"."), + }; + properties['debugServer'] = { + type: 'number', + description: nls.localize('debugServer', "For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode"), + default: 4711 + }; + properties['preLaunchTask'] = { + type: ['string', 'null'], + default: '', + description: nls.localize('debugPrelaunchTask', "Task to run before debug session starts.") + }; + properties['postDebugTask'] = { + type: ['string', 'null'], + default: '', + description: nls.localize('debugPostDebugTask', "Task to run after debug session ends.") + }; + properties['internalConsoleOptions'] = INTERNAL_CONSOLE_OPTIONS_SCHEMA; + + const osProperties = objects.deepClone(properties); + properties['windows'] = { + type: 'object', + description: nls.localize('debugWindowsConfiguration', "Windows specific launch configuration attributes."), + properties: osProperties + }; + properties['osx'] = { + type: 'object', + description: nls.localize('debugOSXConfiguration', "OS X specific launch configuration attributes."), + properties: osProperties + }; + properties['linux'] = { + type: 'object', + description: nls.localize('debugLinuxConfiguration', "Linux specific launch configuration attributes."), + properties: osProperties + }; + Object.keys(attributes.properties).forEach(name => { + // Use schema allOf property to get independent error reporting #21113 + attributes.properties[name].pattern = attributes.properties[name].pattern || '^(?!.*\\$\\{(env|config|command)\\.)'; + attributes.properties[name].patternErrorMessage = attributes.properties[name].patternErrorMessage || + nls.localize('deprecatedVariables', "'env.', 'config.' and 'command.' are deprecated, use 'env:', 'config:' and 'command:' instead."); + }); + + return attributes; + }); + } +} diff --git a/src/vs/workbench/parts/debug/node/v8Protocol.ts b/src/vs/workbench/parts/debug/node/v8Protocol.ts deleted file mode 100644 index efac7e46afa..00000000000 --- a/src/vs/workbench/parts/debug/node/v8Protocol.ts +++ /dev/null @@ -1,155 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as stream from 'stream'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { canceled } from 'vs/base/common/errors'; - -export abstract class V8Protocol { - - private static readonly TWO_CRLF = '\r\n\r\n'; - - private outputStream: stream.Writable; - private sequence: number; - private pendingRequests: Map void>; - private rawData: Buffer; - private contentLength: number; - - constructor(private id: string) { - this.sequence = 1; - this.contentLength = -1; - this.pendingRequests = new Map void>(); - this.rawData = Buffer.allocUnsafe(0); - } - - public getId(): string { - return this.id; - } - - protected abstract onServerError(err: Error): void; - protected abstract onEvent(event: DebugProtocol.Event): void; - protected abstract dispatchRequest(request: DebugProtocol.Request, response: DebugProtocol.Response): void; - - protected connect(readable: stream.Readable, writable: stream.Writable): void { - - this.outputStream = writable; - - readable.on('data', (data: Buffer) => { - this.rawData = Buffer.concat([this.rawData, data]); - this.handleData(); - }); - } - - protected send(command: string, args: any): TPromise { - let errorCallback: (error: Error) => void; - return new TPromise((completeDispatch, errorDispatch) => { - errorCallback = errorDispatch; - this.doSend(command, args, (result: R) => { - if (result.success) { - completeDispatch(result); - } else { - errorDispatch(result); - } - }); - }, () => errorCallback(canceled())); - } - - public sendResponse(response: DebugProtocol.Response): void { - if (response.seq > 0) { - console.error(`attempt to send more than one response for command ${response.command}`); - } else { - this.sendMessage('response', response); - } - } - - private doSend(command: string, args: any, clb: (result: DebugProtocol.Response) => void): void { - - const request: any = { - command: command - }; - if (args && Object.keys(args).length > 0) { - request.arguments = args; - } - - this.sendMessage('request', request); - - if (clb) { - // store callback for this request - this.pendingRequests.set(request.seq, clb); - } - } - - private sendMessage(typ: 'request' | 'response' | 'event', message: DebugProtocol.ProtocolMessage): void { - - message.type = typ; - message.seq = this.sequence++; - - const json = JSON.stringify(message); - const length = Buffer.byteLength(json, 'utf8'); - - this.outputStream.write('Content-Length: ' + length.toString() + V8Protocol.TWO_CRLF, 'utf8'); - this.outputStream.write(json, 'utf8'); - } - - private handleData(): void { - while (true) { - if (this.contentLength >= 0) { - if (this.rawData.length >= this.contentLength) { - const message = this.rawData.toString('utf8', 0, this.contentLength); - this.rawData = this.rawData.slice(this.contentLength); - this.contentLength = -1; - if (message.length > 0) { - this.dispatch(message); - } - continue; // there may be more complete messages to process - } - } else { - const s = this.rawData.toString('utf8', 0, this.rawData.length); - const idx = s.indexOf(V8Protocol.TWO_CRLF); - if (idx !== -1) { - const match = /Content-Length: (\d+)/.exec(s); - if (match && match[1]) { - this.contentLength = Number(match[1]); - this.rawData = this.rawData.slice(idx + V8Protocol.TWO_CRLF.length); - continue; // try to handle a complete message - } - } - } - break; - } - } - - private dispatch(body: string): void { - try { - const rawData = JSON.parse(body); - switch (rawData.type) { - case 'event': - this.onEvent(rawData); - break; - case 'response': - const response = rawData; - const clb = this.pendingRequests.get(response.request_seq); - if (clb) { - this.pendingRequests.delete(response.request_seq); - clb(response); - } - break; - case 'request': - const request = rawData; - const resp: DebugProtocol.Response = { - type: 'response', - seq: 0, - command: request.command, - request_seq: request.seq, - success: true - }; - this.dispatchRequest(request, resp); - break; - } - } catch (e) { - this.onServerError(new Error((e.message || e) + '\n' + body)); - } - } -} diff --git a/src/vs/workbench/parts/debug/test/node/debugAdapter.test.ts b/src/vs/workbench/parts/debug/test/node/debugger.test.ts similarity index 52% rename from src/vs/workbench/parts/debug/test/node/debugAdapter.test.ts rename to src/vs/workbench/parts/debug/test/node/debugger.test.ts index bc4cfc87f6c..8a0379957c9 100644 --- a/src/vs/workbench/parts/debug/test/node/debugAdapter.test.ts +++ b/src/vs/workbench/parts/debug/test/node/debugger.test.ts @@ -6,15 +6,17 @@ import * as assert from 'assert'; import * as paths from 'vs/base/common/paths'; import * as platform from 'vs/base/common/platform'; -import { IRawAdapter, IAdapterExecutable, IConfigurationManager } from 'vs/workbench/parts/debug/common/debug'; -import { Adapter } from 'vs/workbench/parts/debug/node/debugAdapter'; +import { IAdapterExecutable, IConfigurationManager } from 'vs/workbench/parts/debug/common/debug'; +import { Debugger } from 'vs/workbench/parts/debug/node/debugger'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import uri from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; +import { DebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; -suite('Debug - Adapter', () => { - let adapter: Adapter; +suite('Debug - Debugger', () => { + let _debugger: Debugger; + const extensionFolderPath = 'a/b/c/'; const rawAdapter = { type: 'mock', @@ -44,6 +46,73 @@ suite('Debug - Adapter', () => { } ] }; + + const extensionDescriptor0 = { + id: 'adapter', + name: 'myAdapter', + version: '1.0.0', + publisher: 'vscode', + extensionFolderPath: extensionFolderPath, + isBuiltin: false, + engines: null, + contributes: { + 'debuggers': [ + rawAdapter + ] + } + }; + + const extensionDescriptor1 = { + id: 'extension1', + name: 'extension1', + version: '1.0.0', + publisher: 'vscode', + extensionFolderPath: '/e1/b/c/', + isBuiltin: false, + engines: null, + contributes: { + 'debuggers': [ + { + type: 'mock', + runtime: 'runtime', + runtimeArgs: ['rarg'], + program: 'mockprogram', + args: ['parg'] + } + ] + } + }; + + const extensionDescriptor2 = { + id: 'extension2', + name: 'extension2', + version: '1.0.0', + publisher: 'vscode', + extensionFolderPath: '/e2/b/c/', + isBuiltin: false, + engines: null, + contributes: { + 'debuggers': [ + { + type: 'mock', + win: { + runtime: 'winRuntime', + program: 'winProgram' + }, + linux: { + runtime: 'linuxRuntime', + program: 'linuxProgram' + }, + osx: { + runtime: 'osxRuntime', + program: 'osxProgram' + } + } + ] + } + }; + + const configurationManager = { debugAdapterExecutable(folderUri: uri | undefined, type: string): TPromise { return TPromise.as(undefined); @@ -51,26 +120,25 @@ suite('Debug - Adapter', () => { }; setup(() => { - adapter = new Adapter(configurationManager, rawAdapter, { extensionFolderPath, id: 'adapter', name: 'myAdapter', version: '1.0.0', publisher: 'vscode', isBuiltin: false, engines: null }, - new TestConfigurationService(), null); + _debugger = new Debugger(configurationManager, rawAdapter, extensionDescriptor0, new TestConfigurationService(), null); }); teardown(() => { - adapter = null; + _debugger = null; }); test('attributes', () => { - assert.equal(adapter.type, rawAdapter.type); - assert.equal(adapter.label, rawAdapter.label); + assert.equal(_debugger.type, rawAdapter.type); + assert.equal(_debugger.label, rawAdapter.label); - return adapter.getAdapterExecutable(undefined, false).then(details => { - assert.equal(details.command, paths.join(extensionFolderPath, rawAdapter.program)); - assert.deepEqual(details.args, rawAdapter.args); - }); + const ae = DebugAdapter.platformAdapterExecutable([extensionDescriptor0], 'mock'); + + assert.equal(ae.command, paths.join(extensionFolderPath, rawAdapter.program)); + assert.deepEqual(ae.args, rawAdapter.args); }); test('schema attributes', () => { - const schemaAttribute = adapter.getSchemaAttributes()[0]; + const schemaAttribute = _debugger.getSchemaAttributes()[0]; assert.notDeepEqual(schemaAttribute, rawAdapter.configurationAttributes); Object.keys(rawAdapter.configurationAttributes.launch).forEach(key => { assert.deepEqual(schemaAttribute[key], rawAdapter.configurationAttributes.launch[key]); @@ -83,38 +151,11 @@ suite('Debug - Adapter', () => { assert.equal(!!schemaAttribute['properties']['preLaunchTask'], true); }); - test('merge', () => { - - const da: IRawAdapter = { - type: 'mock', - win: { - runtime: 'winRuntime' - }, - linux: { - runtime: 'linuxRuntime' - }, - osx: { - runtime: 'osxRuntime' - }, - runtimeArgs: ['first arg'], - program: 'mockprogram', - args: ['arg'] - }; - - adapter.merge(da, { - name: 'my name', - id: 'my_id', - version: '1.0', - publisher: 'mockPublisher', - isBuiltin: true, - extensionFolderPath: 'a/b/c/d', - engines: null - }); - - return adapter.getAdapterExecutable(undefined, false).then(details => { - assert.equal(details.command, platform.isLinux ? da.linux.runtime : platform.isMacintosh ? da.osx.runtime : da.win.runtime); - assert.deepEqual(details.args, da.runtimeArgs.concat(['a/b/c/d/mockprogram'].concat(da.args))); - }); + test('merge platform specific attributes', () => { + const ae = DebugAdapter.platformAdapterExecutable([extensionDescriptor1, extensionDescriptor2], 'mock'); + assert.equal(ae.command, platform.isLinux ? 'linuxRuntime' : (platform.isMacintosh ? 'osxRuntime' : 'winRuntime')); + const xprogram = platform.isLinux ? 'linuxProgram' : (platform.isMacintosh ? 'osxProgram' : 'winProgram'); + assert.deepEqual(ae.args, ['rarg', '/e2/b/c/' + xprogram, 'parg']); }); test('initial config file content', () => { @@ -134,7 +175,7 @@ suite('Debug - Adapter', () => { ' ]', '}'].join('\n'); - return adapter.getInitialConfigurationContent().then(content => { + return _debugger.getInitialConfigurationContent().then(content => { assert.equal(content, expected); }, err => assert.fail(err)); }); diff --git a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts index d0cb9e4f524..9d7bc2cd1ab 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts @@ -509,7 +509,7 @@ export class TerminalTaskSystem implements ITaskSystem { let cwd = options && options.cwd ? options.cwd : process.cwd(); // On Windows executed process must be described absolute. Since we allowed command without an // absolute path (e.g. "command": "node") we need to find the executable in the CWD or PATH. - let executable = Platform.isWindows && !isShellCommand ? this.findExecutable(commandExecutable, cwd) : commandExecutable; + let executable = Platform.isWindows && !isShellCommand ? this.findExecutable(commandExecutable, cwd, options) : commandExecutable; // When we have a process task there is no need to quote arguments. So we go ahead and take the string value. shellLaunchConfig = { @@ -688,23 +688,39 @@ export class TerminalTaskSystem implements ITaskSystem { return { command, args }; } - private findExecutable(command: string, cwd: string): string { + private findExecutable(command: string, cwd: string, options: CommandOptions): string { // If we have an absolute path then we take it. if (path.isAbsolute(command)) { return command; } let dir = path.dirname(command); if (dir !== '.') { - // We have a directory. Make the path absolute - // to the current working directory + // We have a directory and the directory is relative (see above). Make the path absolute + // to the current working directory. + return path.join(cwd, command); + } + let paths: string[] = undefined; + // The options can override the PATH. So consider that PATH if present. + if (options && options.env) { + // Path can be named in many different ways and for the execution it doesn't matter + for (let key of Object.keys(options.env)) { + if (key.toLowerCase() === 'path') { + if (Types.isString(options.env[key])) { + paths = options.env[key].split(path.delimiter); + } + break; + } + } + } + if (paths === void 0 && Types.isString(process.env.PATH)) { + paths = process.env.PATH.split(path.delimiter); + } + // No PATH environment. Make path absolute to the cwd. + if (paths === void 0 || paths.length === 0) { return path.join(cwd, command); } // We have a simple file name. We get the path variable from the env // and try to find the executable on the path. - if (!process.env.PATH) { - return command; - } - let paths: string[] = (process.env.PATH as string).split(path.delimiter); for (let pathEntry of paths) { // The path entry is absolute. let fullPath: string; diff --git a/src/vs/workbench/parts/terminal/node/terminalProcess.ts b/src/vs/workbench/parts/terminal/node/terminalProcess.ts index 008da19c4d6..e3a73831538 100644 --- a/src/vs/workbench/parts/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/parts/terminal/node/terminalProcess.ts @@ -43,7 +43,7 @@ if (cols && rows) { options.rows = parseInt(rows, 10); } -var ptyProcess = pty.fork(shell, args, options); +var ptyProcess = pty.spawn(shell, args, options); var closeTimeout: number; var exitCode: number; @@ -91,9 +91,9 @@ process.on('message', function (message) { sendProcessId(); setupTitlePolling(); -function getArgs(): string[] { +function getArgs(): string | string[] { if (process.env['PTYSHELLCMDLINE']) { - return [process.env['PTYSHELLCMDLINE']]; + return process.env['PTYSHELLCMDLINE']; } var args = []; var i = 0; diff --git a/src/vs/workbench/parts/terminal/test/electron-browser/terminalCommandTracker.test.ts b/src/vs/workbench/parts/terminal/test/electron-browser/terminalCommandTracker.test.ts new file mode 100644 index 00000000000..262847d1d80 --- /dev/null +++ b/src/vs/workbench/parts/terminal/test/electron-browser/terminalCommandTracker.test.ts @@ -0,0 +1,116 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as assert from 'assert'; +import { Terminal } from 'vscode-xterm'; +import { TerminalCommandTracker } from 'vs/workbench/parts/terminal/node/terminalCommandTracker'; + +interface TestTerminal extends Terminal { + writeBuffer: string[]; + _innerWrite(): void; +} + +function syncWrite(term: TestTerminal, data: string): void { + // Terminal.write is asynchronous + term.writeBuffer.push(data); + term._innerWrite(); +} + +const ROWS = 10; +const COLS = 10; + +suite('Workbench - TerminalCommandTracker', () => { + let xterm: TestTerminal; + let commandTracker: TerminalCommandTracker; + + setup(() => { + xterm = (new Terminal({ + cols: COLS, + rows: ROWS + })); + // Fill initial viewport + for (let i = 0; i < ROWS - 1; i++) { + syncWrite(xterm, `${i}\n`); + } + commandTracker = new TerminalCommandTracker(xterm); + }); + + suite('Command tracking', () => { + test('should track commands when the prompt is of sufficient size', () => { + assert.equal(xterm.markers.length, 0); + syncWrite(xterm, '\x1b[3G'); // Move cursor to column 3 + xterm.emit('key', '\x0d'); + assert.equal(xterm.markers.length, 1); + }); + test('should not track commands when the prompt is too small', () => { + assert.equal(xterm.markers.length, 0); + syncWrite(xterm, '\x1b[2G'); // Move cursor to column 2 + xterm.emit('key', '\x0d'); + assert.equal(xterm.markers.length, 0); + }); + }); + + suite('Commands', () => { + test('should scroll to the next and previous commands', () => { + syncWrite(xterm, '\x1b[3G'); // Move cursor to column 3 + xterm.emit('key', '\x0d'); // Mark line #10 + assert.equal(xterm.markers[0].line, 9); + + for (let i = 0; i < 20; i++) { + syncWrite(xterm, `\r\n`); + } + assert.equal(xterm.buffer.ybase, 20); + assert.equal(xterm.buffer.ydisp, 20); + + // Scroll to marker + commandTracker.scrollToPreviousCommand(); + assert.equal(xterm.buffer.ydisp, 9); + + // Scroll to top boundary + commandTracker.scrollToPreviousCommand(); + assert.equal(xterm.buffer.ydisp, 0); + + // Scroll to marker + commandTracker.scrollToNextCommand(); + assert.equal(xterm.buffer.ydisp, 9); + + // Scroll to bottom boundary + commandTracker.scrollToNextCommand(); + assert.equal(xterm.buffer.ydisp, 20); + }); + // test('should select to the next and previous commands', () => { + // (window).matchMedia = () => { + // return { addListener: () => {} } + // }; + // xterm.open(document.createElement('div')); + + // syncWrite(xterm, '\r0'); + // syncWrite(xterm, '\n\r1'); + // syncWrite(xterm, '\x1b[3G'); // Move cursor to column 3 + // xterm.emit('key', '\x0d'); // Mark line + // assert.equal(xterm.markers[0].line, 10); + // syncWrite(xterm, '\n\r2'); + // syncWrite(xterm, '\x1b[3G'); // Move cursor to column 3 + // xterm.emit('key', '\x0d'); // Mark line + // assert.equal(xterm.markers[1].line, 11); + // syncWrite(xterm, '\n\r3'); + + // assert.equal(xterm.buffer.ybase, 3); + // assert.equal(xterm.buffer.ydisp, 3); + + // assert.equal(xterm.getSelection(), ''); + // commandTracker.selectToPreviousCommand(); + // assert.equal(xterm.getSelection(), '2'); + // commandTracker.selectToPreviousCommand(); + // assert.equal(xterm.getSelection(), '1\n2'); + // commandTracker.selectToNextCommand(); + // assert.equal(xterm.getSelection(), '2'); + // commandTracker.selectToNextCommand(); + // assert.equal(xterm.getSelection(), '\n'); + // }); + }); +}); \ No newline at end of file diff --git a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts index 2bee4041a3c..6e67631266e 100644 --- a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts +++ b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts @@ -131,13 +131,16 @@ function validateProperties(configuration: IConfigurationNode, extension: IExten for (let key in properties) { const message = validateProperty(key); const propertyConfiguration = configuration.properties[key]; - propertyConfiguration.scope = ConfigurationScope.WINDOW; if (propertyConfiguration.scope) { if (propertyConfiguration.scope.toString() === 'application') { propertyConfiguration.scope = ConfigurationScope.APPLICATION; } else if (propertyConfiguration.scope.toString() === 'resource') { propertyConfiguration.scope = ConfigurationScope.RESOURCE; + } else { + propertyConfiguration.scope = ConfigurationScope.WINDOW; } + } else { + propertyConfiguration.scope = ConfigurationScope.WINDOW; } propertyConfiguration.notMultiRootAdopted = !(extension.description.isBuiltin || (Array.isArray(extension.description.keywords) && extension.description.keywords.indexOf('multi-root ready') !== -1)); if (message) { diff --git a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts index 6382148634b..5c323ca2409 100644 --- a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts +++ b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts @@ -18,7 +18,6 @@ import { unmnemonicLabel } from 'vs/base/common/labels'; import { Event, Emitter } from 'vs/base/common/event'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IContextMenuDelegate, ContextSubMenu, IEvent } from 'vs/base/browser/contextmenu'; -import { once } from 'vs/base/common/functional'; export class ContextMenuService implements IContextMenuService { @@ -43,15 +42,7 @@ export class ContextMenuService implements IContextMenuService { } return TPromise.timeout(0).then(() => { // https://github.com/Microsoft/vscode/issues/3638 - const onHide = once(() => { - if (delegate.onHide) { - delegate.onHide(undefined); - } - - this._onDidContextMenu.fire(); - }); - - const menu = this.createMenu(delegate, actions, onHide); + const menu = this.createMenu(delegate, actions); const anchor = delegate.getAnchor(); let x: number, y: number; @@ -70,18 +61,16 @@ export class ContextMenuService implements IContextMenuService { x *= zoom; y *= zoom; - menu.popup({ - window: remote.getCurrentWindow(), - x: Math.floor(x), - y: Math.floor(y), - positioningItem: delegate.autoSelectFirstItem ? 0 : void 0, - callback: () => onHide() - }); + menu.popup(remote.getCurrentWindow(), { x: Math.floor(x), y: Math.floor(y), positioningItem: delegate.autoSelectFirstItem ? 0 : void 0 }); + this._onDidContextMenu.fire(); + if (delegate.onHide) { + delegate.onHide(undefined); + } }); }); } - private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[], onHide: () => void): Electron.Menu { + private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[]): Electron.Menu { const menu = new remote.Menu(); const actionRunner = delegate.actionRunner || new ActionRunner(); @@ -90,7 +79,7 @@ export class ContextMenuService implements IContextMenuService { menu.append(new remote.MenuItem({ type: 'separator' })); } else if (e instanceof ContextSubMenu) { const submenu = new remote.MenuItem({ - submenu: this.createMenu(delegate, e.entries, onHide), + submenu: this.createMenu(delegate, e.entries), label: unmnemonicLabel(e.label) }); @@ -102,13 +91,6 @@ export class ContextMenuService implements IContextMenuService { type: !!e.checked ? 'checkbox' : !!e.radio ? 'radio' : void 0, enabled: !!e.enabled, click: (menuItem, win, event) => { - - // To preserve pre-electron-2.x behaviour, we first trigger - // the onHide callback and then the action. - // Fixes https://github.com/Microsoft/vscode/issues/45601 - onHide(); - - // Run action which will close the menu this.runAction(actionRunner, e, delegate, event); } }; diff --git a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts index 7dc0e037da8..95a5a332c4d 100644 --- a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts @@ -130,7 +130,7 @@ const schema: IJSONSchema = { 'vscode': { type: 'string', description: nls.localize('vscode.extension.engines.vscode', 'For VS Code extensions, specifies the VS Code version that the extension is compatible with. Cannot be *. For example: ^0.10.5 indicates compatibility with a minimum VS Code version of 0.10.5.'), - default: '^0.10.0', + default: '^1.22.0', } } }, diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index c57272a6b22..66300311b7b 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -193,13 +193,13 @@ export class ExtensionHostProcessWorker { }, 100); // Print out extension host output - onDebouncedOutput(output => { - const inspectorUrlMatch = !this._environmentService.isBuilt && output.data && output.data.match(/ws:\/\/([^\s]+)/); - if (inspectorUrlMatch) { - console.log(`%c[Extension Host] %cdebugger inspector at chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${inspectorUrlMatch[1]}`, 'color: blue', 'color: black'); + onDebouncedOutput(data => { + const inspectorUrlIndex = !this._environmentService.isBuilt && data.data && data.data.indexOf('chrome-devtools://'); + if (inspectorUrlIndex >= 0) { + console.log(`%c[Extension Host] %cdebugger inspector at ${data.data.substr(inspectorUrlIndex)}`, 'color: blue', 'color: black'); } else { console.group('Extension Host'); - console.log(output.data, ...output.format); + console.log(data.data, ...data.format); console.groupEnd(); } }); diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index cb2fa1e771f..7ea4e454d3c 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -229,10 +229,6 @@ export class FileService implements IFileService { return this.raw.createFolder(resource); } - public touchFile(resource: uri): TPromise { - return this.raw.touchFile(resource); - } - public rename(resource: uri, newName: string): TPromise { return this.raw.rename(resource, newName); } diff --git a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts index 8ea31395c81..b486a7180f5 100644 --- a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts +++ b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts @@ -12,7 +12,6 @@ import { posix } from 'path'; import { IDisposable } from 'vs/base/common/lifecycle'; import { isFalsyOrEmpty, distinct } from 'vs/base/common/arrays'; import { Schemas } from 'vs/base/common/network'; -import { Progress } from 'vs/platform/progress/common/progress'; import { decodeStream, encode, UTF8, UTF8_with_bom, detectEncodingFromBuffer, maxEncodingDetectionBufferLen } from 'vs/base/node/encoding'; import { TernarySearchTree } from 'vs/base/common/map'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -213,7 +212,7 @@ export class RemoteFileService extends FileService { if (resource.scheme === Schemas.file) { return super.resolveContent(resource, options); } else { - return this._doResolveContent(resource, options).then(RemoteFileService._asContent); + return this._readFile(resource, options).then(RemoteFileService._asContent); } } @@ -221,11 +220,11 @@ export class RemoteFileService extends FileService { if (resource.scheme === Schemas.file) { return super.resolveStreamContent(resource, options); } else { - return this._doResolveContent(resource, options); + return this._readFile(resource, options); } } - private _doResolveContent(resource: URI, options: IResolveContentOptions = Object.create(null)): TPromise { + private _readFile(resource: URI, options: IResolveContentOptions = Object.create(null)): TPromise { return this._withProvider(resource).then(provider => { return this.resolveFile(resource).then(fileStat => { @@ -249,15 +248,11 @@ export class RemoteFileService extends FileService { const guessEncoding = options.autoGuessEncoding; const count = maxEncodingDetectionBufferLen(options); - const chunks: Buffer[] = []; - - return provider.read( - resource, - 0, count, - new Progress(chunk => chunks.push(chunk)) - ).then(bytesRead => { - return detectEncodingFromBuffer({ bytesRead, buffer: Buffer.concat(chunks) }, guessEncoding); + let buffer: Buffer; + return provider.readFile(resource).then(data => { + buffer = Buffer.from(data); + return detectEncodingFromBuffer({ bytesRead: Math.min(count, buffer.length), buffer }, guessEncoding); }).then(detected => { if (options.acceptTextOnly && detected.seemsBinary) { return TPromise.wrapError(new FileOperationError( @@ -289,27 +284,7 @@ export class RemoteFileService extends FileService { // const encoding = this.getEncoding(resource); const stream = decodeStream(preferredEncoding); - - // start with what we have already read - // and have a new stream to read the rest - let offset = 0; - for (const chunk of chunks) { - stream.write(chunk); - offset += chunk.length; - } - if (offset < count) { - // we didn't read enough the first time which means - // that we are done - stream.end(); - } else { - // there is more to read - provider.read(resource, offset, -1, new Progress(chunk => stream.write(chunk))).then(() => { - stream.end(); - }, err => { - stream.emit('error', err); - stream.end(); - }); - } + stream.end(buffer); return { encoding: preferredEncoding, @@ -340,7 +315,7 @@ export class RemoteFileService extends FileService { if (exists && options && !options.overwrite) { return TPromise.wrapError(new FileOperationError('EEXIST', FileOperationResult.FILE_MODIFIED_SINCE, options)); } - return this._doUpdateContent(provider, resource, content || '', {}); + return this._writeFile(provider, resource, content || '', {}); }).then(fileStat => { this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.CREATE, fileStat)); return fileStat; @@ -354,15 +329,15 @@ export class RemoteFileService extends FileService { return super.updateContent(resource, value, options); } else { return this._withProvider(resource).then(provider => { - return this._doUpdateContent(provider, resource, value, options || {}); + return this._writeFile(provider, resource, value, options || {}); }); } } - private _doUpdateContent(provider: IFileSystemProvider, resource: URI, content: string | ITextSnapshot, options: IUpdateContentOptions): TPromise { + private _writeFile(provider: IFileSystemProvider, resource: URI, content: string | ITextSnapshot, options: IUpdateContentOptions): TPromise { const encoding = this.getEncoding(resource, options.encoding); // TODO@Joh support streaming API for remote file system writes - return provider.write(resource, encode(typeof content === 'string' ? content : snapshotToString(content), encoding)).then(() => { + return provider.writeFile(resource, encode(typeof content === 'string' ? content : snapshotToString(content), encoding)).then(() => { return this.resolveFile(resource); }); } @@ -390,9 +365,7 @@ export class RemoteFileService extends FileService { return super.del(resource, useTrash); } else { return this._withProvider(resource).then(provider => { - return provider.stat(resource).then(stat => { - return stat.type === FileType.Dir ? provider.rmdir(resource) : provider.unlink(resource); - }).then(() => { + return provider.delete(resource).then(() => { this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.DELETE)); }); }); @@ -483,7 +456,7 @@ export class RemoteFileService extends FileService { // https://github.com/Microsoft/vscode/issues/41543 return this.resolveContent(source, { acceptTextOnly: true }).then(content => { return this._withProvider(target).then(provider => { - return this._doUpdateContent(provider, target, content.value, { encoding: content.encoding }).then(fileStat => { + return this._writeFile(provider, target, content.value, { encoding: content.encoding }).then(fileStat => { this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat)); return fileStat; }); @@ -497,27 +470,6 @@ export class RemoteFileService extends FileService { }); }); }); - - } - - touchFile(resource: URI): TPromise { - if (resource.scheme === Schemas.file) { - return super.touchFile(resource); - } else { - return this._doTouchFile(resource); - } - } - - private _doTouchFile(resource: URI): TPromise { - return this._withProvider(resource).then(provider => { - return provider.stat(resource).then(() => { - return provider.utimes(resource, Date.now(), Date.now()); - }, err => { - return provider.write(resource, new Uint8Array(0)); - }).then(() => { - return this.resolveFile(resource); - }); - }); } // TODO@Joh - file watching on demand! diff --git a/src/vs/workbench/services/files/node/fileService.ts b/src/vs/workbench/services/files/node/fileService.ts index 1c97219d8c1..c73b17c1d36 100644 --- a/src/vs/workbench/services/files/node/fileService.ts +++ b/src/vs/workbench/services/files/node/fileService.ts @@ -536,8 +536,8 @@ export class FileService implements IFileService { private doUpdateContent(resource: uri, value: string | ITextSnapshot, options: IUpdateContentOptions = Object.create(null)): TPromise { const absolutePath = this.toAbsolutePath(resource); - // 1.) check file - return this.checkFile(absolutePath, options).then(exists => { + // 1.) check file for writing + return this.checkFileBeforeWriting(absolutePath, options).then(exists => { let createParentsPromise: TPromise; if (exists) { createParentsPromise = TPromise.as(null); @@ -653,8 +653,8 @@ export class FileService implements IFileService { private doUpdateContentElevated(resource: uri, value: string | ITextSnapshot, options: IUpdateContentOptions = Object.create(null)): TPromise { const absolutePath = this.toAbsolutePath(resource); - // 1.) check file - return this.checkFile(absolutePath, options, options.overwriteReadonly /* ignore readonly if we overwrite readonly, this is handled via sudo later */).then(exists => { + // 1.) check file for writing + return this.checkFileBeforeWriting(absolutePath, options, options.overwriteReadonly /* ignore readonly if we overwrite readonly, this is handled via sudo later */).then(exists => { const writeOptions: IUpdateContentOptions = objects.assign(Object.create(null), options); writeOptions.writeElevated = false; writeOptions.encoding = this.getEncoding(resource, options.encoding); @@ -757,31 +757,68 @@ export class FileService implements IFileService { }); } - public touchFile(resource: uri): TPromise { - const absolutePath = this.toAbsolutePath(resource); - - // 1.) check file - return this.checkFile(absolutePath).then(exists => { - let createPromise: TPromise; + private checkFileBeforeWriting(absolutePath: string, options: IUpdateContentOptions = Object.create(null), ignoreReadonly?: boolean): TPromise { + return pfs.exists(absolutePath).then(exists => { if (exists) { - createPromise = TPromise.as(null); - } else { - createPromise = this.createFile(resource); + return pfs.stat(absolutePath).then(stat => { + if (stat.isDirectory()) { + return TPromise.wrapError(new Error('Expected file is actually a directory')); + } + + // Dirty write prevention: if the file on disk has been changed and does not match our expected + // mtime and etag, we bail out to prevent dirty writing. + // + // First, we check for a mtime that is in the future before we do more checks. The assumption is + // that only the mtime is an indicator for a file that has changd on disk. + // + // Second, if the mtime has advanced, we compare the size of the file on disk with our previous + // one using the etag() function. Relying only on the mtime check has prooven to produce false + // positives due to file system weirdness (especially around remote file systems). As such, the + // check for size is a weaker check because it can return a false negative if the file has changed + // but to the same length. This is a compromise we take to avoid having to produce checksums of + // the file content for comparison which would be much slower to compute. + if (typeof options.mtime === 'number' && typeof options.etag === 'string' && options.mtime < stat.mtime.getTime() && options.etag !== etag(stat.size, options.mtime)) { + return TPromise.wrapError(new FileOperationError(nls.localize('fileModifiedError', "File Modified Since"), FileOperationResult.FILE_MODIFIED_SINCE, options)); + } + + // Throw if file is readonly and we are not instructed to overwrite + if (!ignoreReadonly && !(stat.mode & 128) /* readonly */) { + if (!options.overwriteReadonly) { + return this.readOnlyError(options); + } + + // Try to change mode to writeable + let mode = stat.mode; + mode = mode | 128; + return pfs.chmod(absolutePath, mode).then(() => { + + // Make sure to check the mode again, it could have failed + return pfs.stat(absolutePath).then(stat => { + if (!(stat.mode & 128) /* readonly */) { + return this.readOnlyError(options); + } + + return exists; + }); + }); + } + + return TPromise.as(exists); + }); } - // 2.) create file as needed - return createPromise.then(() => { - - // 3.) update atime and mtime - return pfs.touch(absolutePath).then(() => { - - // 4.) resolve - return this.resolve(resource); - }); - }); + return TPromise.as(exists); }); } + private readOnlyError(options: IUpdateContentOptions): TPromise { + return TPromise.wrapError(new FileOperationError( + nls.localize('fileReadOnlyError', "File is Read Only"), + FileOperationResult.FILE_READ_ONLY, + options + )); + } + public rename(resource: uri, newName: string): TPromise { const newPath = paths.join(paths.dirname(resource.fsPath), newName); @@ -990,61 +1027,6 @@ export class FileService implements IFileService { return null; } - private checkFile(absolutePath: string, options: IUpdateContentOptions = Object.create(null), ignoreReadonly?: boolean): TPromise { - return pfs.exists(absolutePath).then(exists => { - if (exists) { - return pfs.stat(absolutePath).then(stat => { - if (stat.isDirectory()) { - return TPromise.wrapError(new Error('Expected file is actually a directory')); - } - - // Dirty write prevention - if (typeof options.mtime === 'number' && typeof options.etag === 'string' && options.mtime < stat.mtime.getTime()) { - - // Find out if content length has changed - if (options.etag !== etag(stat.size, options.mtime)) { - return TPromise.wrapError(new FileOperationError(nls.localize('fileModifiedError', "File Modified Since"), FileOperationResult.FILE_MODIFIED_SINCE, options)); - } - } - - // Throw if file is readonly and we are not instructed to overwrite - if (!ignoreReadonly && !(stat.mode & 128) /* readonly */) { - if (!options.overwriteReadonly) { - return this.readOnlyError(options); - } - - // Try to change mode to writeable - let mode = stat.mode; - mode = mode | 128; - return pfs.chmod(absolutePath, mode).then(() => { - - // Make sure to check the mode again, it could have failed - return pfs.stat(absolutePath).then(stat => { - if (!(stat.mode & 128) /* readonly */) { - return this.readOnlyError(options); - } - - return exists; - }); - }); - } - - return TPromise.as(exists); - }); - } - - return TPromise.as(exists); - }); - } - - private readOnlyError(options: IUpdateContentOptions): TPromise { - return TPromise.wrapError(new FileOperationError( - nls.localize('fileReadOnlyError', "File is Read Only"), - FileOperationResult.FILE_READ_ONLY, - options - )); - } - public watchFileChanges(resource: uri): void { assert.ok(resource && resource.scheme === Schemas.file, `Invalid resource for watching: ${resource}`); diff --git a/src/vs/workbench/services/files/test/node/fileService.test.ts b/src/vs/workbench/services/files/test/node/fileService.test.ts index 81b1537aa7f..fb5aceb59bd 100644 --- a/src/vs/workbench/services/files/test/node/fileService.test.ts +++ b/src/vs/workbench/services/files/test/node/fileService.test.ts @@ -22,7 +22,6 @@ import { TestEnvironmentService, TestContextService, TestTextResourceConfigurati import { Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TextModel } from 'vs/editor/common/model/textModel'; -import { timeout } from 'vs/base/common/async'; suite('FileService', () => { let service: FileService; @@ -148,44 +147,6 @@ suite('FileService', () => { }); }); - test('touchFile', function () { - return service.touchFile(uri.file(path.join(testDir, 'test.txt'))).then(s => { - assert.equal(s.name, 'test.txt'); - assert.equal(fs.existsSync(s.resource.fsPath), true); - assert.equal(fs.readFileSync(s.resource.fsPath).length, 0); - - const stat = fs.statSync(s.resource.fsPath); - - return timeout(10).then(() => { - return service.touchFile(s.resource).then(s => { - const statNow = fs.statSync(s.resource.fsPath); - assert.ok(statNow.mtime.getTime() >= stat.mtime.getTime()); // one some OS the resolution seems to be 1s, so we use >= here - assert.equal(statNow.size, stat.size); - }); - }); - }); - }); - - test('touchFile - multi folder', function () { - const multiFolderPaths = ['a', 'couple', 'of', 'folders']; - - return service.touchFile(uri.file(path.join(testDir, ...multiFolderPaths, 'test.txt'))).then(s => { - assert.equal(s.name, 'test.txt'); - assert.equal(fs.existsSync(s.resource.fsPath), true); - assert.equal(fs.readFileSync(s.resource.fsPath).length, 0); - - const stat = fs.statSync(s.resource.fsPath); - - return timeout(10).then(() => { - return service.touchFile(s.resource).then(s => { - const statNow = fs.statSync(s.resource.fsPath); - assert.ok(statNow.mtime.getTime() >= stat.mtime.getTime()); // one some OS the resolution seems to be 1s, so we use >= here - assert.equal(statNow.size, stat.size); - }); - }); - }); - }); - test('renameFile', function () { let event: FileOperationEvent; const toDispose = service.onAfterOperation(e => { diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index c39a6227749..0d21aa80ead 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -278,8 +278,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // It is very important to not reload the model when the model is dirty. We only want to reload the model from the disk // if no save is pending to avoid data loss. This might cause a save conflict in case the file has been modified on the disk // meanwhile, but this is a very low risk. - if (this.dirty) { - diag('load() - exit - without loading because model is dirty', this.resource, new Date()); + if (this.dirty || this.saveSequentializer.hasPendingSave()) { + diag('load() - exit - without loading because model is dirty or being saved', this.resource, new Date()); return TPromise.as(this); } @@ -692,16 +692,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // mark the save participant as current pending save operation return this.saveSequentializer.setPending(versionId, saveParticipantPromise.then(newVersionId => { - // Under certain conditions a save to the model will not cause the contents to the flushed on - // disk because we can assume that the contents are already on disk. Instead, we just touch the - // file to still trigger external file watchers for example. + // Under certain conditions we do a short-cut of flushing contents to disk when we can assume that + // the file has not changed and as such was not dirty before. // The conditions are all of: // - a forced, explicit save (Ctrl+S) // - the model is not dirty (otherwise we know there are changed which needs to go to the file) // - the model is not in orphan mode (because in that case we know the file does not exist on disk) // - the model version did not change due to save participants running if (options.force && !this.dirty && !this.inOrphanMode && options.reason === SaveReason.EXPLICIT && versionId === newVersionId) { - return this.doTouch(); + return this.doTouch(newVersionId); } // update versionId with its new value (if pre-save changes happened) @@ -791,12 +790,16 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil }); } - private doTouch(): TPromise { - return this.fileService.touchFile(this.resource).then(stat => { + private doTouch(versionId: number): TPromise { + return this.saveSequentializer.setPending(versionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot(), { + mtime: this.lastResolvedDiskStat.mtime, + encoding: this.getEncoding(), + etag: this.lastResolvedDiskStat.etag + }).then(stat => { // Updated resolved stat with updated stat since touching it might have changed mtime this.updateLastResolvedDiskStat(stat); - }, () => void 0 /* gracefully ignore errors if just touching */); + }, () => void 0 /* gracefully ignore errors if just touching */)); } private setDirty(dirty: boolean): () => void { @@ -842,8 +845,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } // Subsequent resolve - make sure that we only assign it if the mtime is equal or has advanced. - // This is essential a If-Modified-Since check on the client ot prevent race conditions from loading - // and saving. If a save comes in late after a revert was called, the mtime could be out of sync. + // This prevents race conditions from loading and saving. If a save comes in late after a revert + // was called, the mtime could be out of sync. else if (this.lastResolvedDiskStat.mtime <= newVersionOnDiskStat.mtime) { this.lastResolvedDiskStat = newVersionOnDiskStat; } diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 7fb344f6341..0ca51d6b653 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -797,10 +797,6 @@ export class TestFileService implements IFileService { return TPromise.as(null); } - touchFile(resource: URI): TPromise { - return TPromise.as(null); - } - canHandleResource(resource: URI): boolean { return resource.scheme === 'file'; } diff --git a/yarn.lock b/yarn.lock index 24ab3f1d6fb..38c1ea2a301 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5583,9 +5583,9 @@ typescript-formatter@7.1.0: commandpost "^1.0.0" editorconfig "^0.15.0" -typescript@2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" +typescript@2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624" typescript@^2.6.2: version "2.6.2" @@ -5927,9 +5927,9 @@ vscode-textmate@^3.3.3: fast-plist "^0.1.2" oniguruma "^6.0.1" -vscode-xterm@3.3.0-beta8: - version "3.3.0-beta8" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.3.0-beta8.tgz#092403d293250e09a38d89a53ce120135e92c778" +vscode-xterm@3.4.0-beta3: + version "3.4.0-beta3" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.4.0-beta3.tgz#349db387bd3669ad4d6044a6ea6d699e6d649fb5" vso-node-api@^6.1.2-preview: version "6.1.2-preview" @@ -5969,9 +5969,9 @@ windows-mutex@^0.2.0: bindings "^1.2.1" nan "^2.1.0" -windows-process-tree@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.0.tgz#04dc0507df292a7984daf0d35861bd1ebaff7ae8" +windows-process-tree@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.1.tgz#d750f8592bd956e89f8dc565bc47be6430d3df6e" dependencies: nan "^2.6.2"