From d865a99c496e677f9aec88771ec4be4b238d91b7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 7 Aug 2025 09:38:52 -0700 Subject: [PATCH] Clean up some typings in build - Adding ts-check in a few more js files - Switching to use `@types` for a few more packages - Remove some unused code --- build/buildfile.js | 1 + build/eslint.js | 2 +- build/filters.js | 1 + build/gulp-eslint.js | 16 +- build/gulpfile.cli.js | 32 +-- build/gulpfile.extensions.js | 14 +- build/gulpfile.js | 2 +- build/gulpfile.vscode.web.js | 8 + build/gulpfile.vscode.win32.js | 1 - build/hygiene.js | 22 +- build/lib/compilation.js | 2 +- build/lib/compilation.ts | 6 +- build/lib/extensions.ts | 4 +- build/lib/i18n.ts | 8 +- build/lib/inlineMeta.ts | 2 +- build/lib/nls.js | 6 +- build/lib/nls.ts | 12 +- build/lib/typings/github-releases.d.ts | 3 - build/lib/typings/gulp-flatmap.d.ts | 12 -- build/lib/typings/lazy.js.d.ts | 276 ------------------------- build/lib/typings/vinyl.d.ts | 135 ------------ build/lib/util.ts | 6 +- build/package-lock.json | 52 +++++ build/package.json | 6 + build/setup-npm-registry.js | 15 +- build/stylelint.js | 8 +- build/tsconfig.build.json | 3 - 27 files changed, 144 insertions(+), 511 deletions(-) delete mode 100644 build/lib/typings/github-releases.d.ts delete mode 100644 build/lib/typings/gulp-flatmap.d.ts delete mode 100644 build/lib/typings/lazy.js.d.ts delete mode 100644 build/lib/typings/vinyl.d.ts diff --git a/build/buildfile.js b/build/buildfile.js index 3acb1218b99..83f84563275 100644 --- a/build/buildfile.js +++ b/build/buildfile.js @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +// @ts-check /** * @param {string} name diff --git a/build/eslint.js b/build/eslint.js index 55e11b277d9..e952c546eec 100644 --- a/build/eslint.js +++ b/build/eslint.js @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - +// @ts-check const es = require('event-stream'); const vfs = require('vinyl-fs'); const { eslintFilter } = require('./filters'); diff --git a/build/filters.js b/build/filters.js index 035bd3ddb91..4a568ded8b0 100644 --- a/build/filters.js +++ b/build/filters.js @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +// @ts-check /** * Hygiene works by creating cascading subsets of all our files and diff --git a/build/gulp-eslint.js b/build/gulp-eslint.js index 902c7b47003..793c16c2f30 100644 --- a/build/gulp-eslint.js +++ b/build/gulp-eslint.js @@ -6,24 +6,28 @@ 'use strict'; const { ESLint } = require('eslint'); -const { Transform } = require('stream'); +const { Transform, default: Stream } = require('stream'); const { relative } = require('path'); const fancyLog = require('fancy-log'); /** - * @param {Function} action - A function to handle all ESLint results - * @returns {stream} gulp file stream + * @typedef {ESLint.LintResult[] & { errorCount: number, warningCount: number}} ESLintResults + */ + +/** + * @param {(results: ESLintResults) => void} action - A function to handle all ESLint results */ function eslint(action) { const linter = new ESLint({}); const formatter = linter.loadFormatter('compact'); + /** @type {ESLintResults} results */ const results = []; results.errorCount = 0; results.warningCount = 0; return transform( - async (file, enc, cb) => { + async (file, _enc, cb) => { const filePath = relative(process.cwd(), file.path); if (file.isNull()) { @@ -67,6 +71,10 @@ function eslint(action) { }); } +/** + * @param {Stream.TransformOptions['transform']} transform + * @param {Stream.TransformOptions['flush']} flush + */ function transform(transform, flush) { return new Transform({ objectMode: true, diff --git a/build/gulpfile.cli.js b/build/gulpfile.cli.js index 592fc74516c..63e0ae0b847 100644 --- a/build/gulpfile.cli.js +++ b/build/gulpfile.cli.js @@ -12,7 +12,7 @@ const fancyLog = require('fancy-log'); const ansiColors = require('ansi-colors'); const cp = require('child_process'); const { tmpdir } = require('os'); -const { promises: fs, existsSync, mkdirSync, rmSync } = require('fs'); +const { existsSync, mkdirSync, rmSync } = require('fs'); const task = require('./lib/task'); const watcher = require('./lib/watch'); @@ -58,36 +58,6 @@ const hasLocalRust = (() => { }; })(); -const debounceEsStream = (fn, duration = 100) => { - let handle = undefined; - let pending = []; - const sendAll = (pending) => (event, ...args) => { - for (const stream of pending) { - pending.emit(event, ...args); - } - }; - - return es.map(function (_, callback) { - console.log('defer'); - if (handle !== undefined) { - clearTimeout(handle); - } - - handle = setTimeout(() => { - handle = undefined; - - const previous = pending; - pending = []; - fn() - .on('error', sendAll('error')) - .on('data', sendAll('data')) - .on('end', sendAll('end')); - }, duration); - - pending.push(this); - }); -}; - const compileFromSources = (callback) => { const proc = cp.spawn('cargo', ['--color', 'always', 'build'], { cwd: root, diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index 73c227e29ae..83d4f32179f 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -92,16 +92,6 @@ const tasks = compilations.map(function (tsconfigFile) { const out = path.join(srcRoot, 'out'); const baseUrl = getBaseUrl(out); - let headerId, headerOut; - const index = relativeDirname.indexOf('/'); - if (index < 0) { - headerId = 'vscode.' + relativeDirname; - headerOut = 'out'; - } else { - headerId = 'vscode.' + relativeDirname.substr(0, index); - headerOut = relativeDirname.substr(index + 1) + '/out'; - } - function createPipeline(build, emitError, transpileOnly) { const tsb = require('./lib/tsb'); const sourcemaps = require('gulp-sourcemaps'); @@ -248,7 +238,7 @@ const bundleMarketplaceExtensionsBuildTask = task.define('bundle-marketplace-ext */ const compileNonNativeExtensionsBuildTask = task.define('compile-non-native-extensions-build', task.series( bundleMarketplaceExtensionsBuildTask, - task.define('bundle-non-native-extensions-build', () => ext.packageNonNativeLocalExtensionsStream().pipe(gulp.dest('.build'))) + task.define('bundle-non-native-extensions-build', () => ext.packageNonNativeLocalExtensionsStream(false, false).pipe(gulp.dest('.build'))) )); gulp.task(compileNonNativeExtensionsBuildTask); exports.compileNonNativeExtensionsBuildTask = compileNonNativeExtensionsBuildTask; @@ -257,7 +247,7 @@ exports.compileNonNativeExtensionsBuildTask = compileNonNativeExtensionsBuildTas * Compiles the native extensions for the build * @note this does not clean the directory ahead of it. See {@link cleanExtensionsBuildTask} for that. */ -const compileNativeExtensionsBuildTask = task.define('compile-native-extensions-build', () => ext.packageNativeLocalExtensionsStream().pipe(gulp.dest('.build'))); +const compileNativeExtensionsBuildTask = task.define('compile-native-extensions-build', () => ext.packageNativeLocalExtensionsStream(false, false).pipe(gulp.dest('.build'))); gulp.task(compileNativeExtensionsBuildTask); exports.compileNativeExtensionsBuildTask = compileNativeExtensionsBuildTask; diff --git a/build/gulpfile.js b/build/gulpfile.js index 7894398c2ea..97971eec63e 100644 --- a/build/gulpfile.js +++ b/build/gulpfile.js @@ -11,7 +11,7 @@ require('events').EventEmitter.defaultMaxListeners = 100; const gulp = require('gulp'); const util = require('./lib/util'); const task = require('./lib/task'); -const { transpileClientSWC, transpileTask, compileTask, watchTask, compileApiProposalNamesTask, watchApiProposalNamesTask } = require('./lib/compilation'); +const { transpileTask, compileTask, watchTask, compileApiProposalNamesTask, watchApiProposalNamesTask } = require('./lib/compilation'); const { monacoTypecheckTask/* , monacoTypecheckWatchTask */ } = require('./gulpfile.editor'); const { compileExtensionsTask, watchExtensionsTask, compileExtensionMediaTask } = require('./gulpfile.extensions'); diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index 08dfcfd0cd9..295a9778d52 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -93,6 +93,10 @@ const vscodeWebEntryPoints = [ * @param {object} product The parsed product.json file contents */ const createVSCodeWebFileContentMapper = (extensionsRoot, product) => { + /** + * @param {string} path + * @returns {((content: string) => string) | undefined} + */ return path => { if (path.endsWith('vs/platform/product/common/product.js')) { return content => { @@ -138,6 +142,10 @@ const minifyVSCodeWebTask = task.define('minify-vscode-web', task.series( )); gulp.task(minifyVSCodeWebTask); +/** + * @param {string} sourceFolderName + * @param {string} destinationFolderName + */ function packageTask(sourceFolderName, destinationFolderName) { const destination = path.join(BUILD_ROOT, destinationFolderName); diff --git a/build/gulpfile.vscode.win32.js b/build/gulpfile.vscode.win32.js index 0c4dc5226cc..9207df5a44b 100644 --- a/build/gulpfile.vscode.win32.js +++ b/build/gulpfile.vscode.win32.js @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - 'use strict'; const gulp = require('gulp'); diff --git a/build/hygiene.js b/build/hygiene.js index c844ebd574b..961b085e684 100644 --- a/build/hygiene.js +++ b/build/hygiene.js @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +// @ts-check const filter = require('gulp-filter'); const es = require('event-stream'); @@ -20,6 +21,10 @@ const copyrightHeaderLines = [ ' *--------------------------------------------------------------------------------------------*/', ]; +/** + * @param {string[] | NodeJS.ReadWriteStream} some + * @param {boolean} linting + */ function hygiene(some, linting = true) { const eslint = require('./gulp-eslint'); const gulpstylelint = require('./stylelint'); @@ -39,6 +44,7 @@ function hygiene(some, linting = true) { }); const unicode = es.through(function (file) { + /** @type {string[]} */ const lines = file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; const allowInComments = lines.some(line => /allow-any-unicode-comment-file/.test(line)); @@ -76,6 +82,7 @@ function hygiene(some, linting = true) { }); const indentation = es.through(function (file) { + /** @type {string[]} */ const lines = file.__lines || file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; @@ -125,14 +132,13 @@ function hygiene(some, linting = true) { ); errorCount++; } - cb(null, file); + cb(undefined, file); } catch (err) { cb(err); } }); let input; - if (Array.isArray(some) || typeof some === 'string' || !some) { const options = { base: '.', follow: true, allowEmpty: true }; if (some) { @@ -164,6 +170,7 @@ function hygiene(some, linting = true) { .pipe(filter(copyrightFilter)) .pipe(copyrights); + /** @type {import('stream').Stream[]} */ const streams = [ result.pipe(filter(tsFormattingFilter)).pipe(formatting) ]; @@ -220,6 +227,9 @@ function hygiene(some, linting = true) { module.exports.hygiene = hygiene; +/** + * @param {string[]} paths + */ function createGitIndexVinyls(paths) { const cp = require('child_process'); const repositoryPath = process.cwd(); @@ -294,12 +304,14 @@ if (require.main === module) { createGitIndexVinyls(some) .then( - (vinyls) => - new Promise((c, e) => + (vinyls) => { + /** @type {Promise} */ + return (new Promise((c, e) => hygiene(es.readArray(vinyls).pipe(filter(all))) .on('end', () => c()) .on('error', e) - ) + )) + } ) .catch((err) => { console.error(); diff --git a/build/lib/compilation.js b/build/lib/compilation.js index 7e0927e9d2f..fb326dfd2b1 100644 --- a/build/lib/compilation.js +++ b/build/lib/compilation.js @@ -123,7 +123,7 @@ function createCompile(src, { build, emitError, transpileOnly, preserveEnglish } } function transpileTask(src, out, esbuild) { const task = () => { - const transpile = createCompile(src, { build: false, emitError: true, transpileOnly: { esbuild }, preserveEnglish: false }); + const transpile = createCompile(src, { build: false, emitError: true, transpileOnly: { esbuild: !!esbuild }, preserveEnglish: false }); const srcPipe = gulp_1.default.src(`${src}/**`, { base: `${src}` }); return srcPipe .pipe(transpile()) diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index a1de9f12dfd..aea06e8a242 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -100,11 +100,11 @@ export function createCompile(src: string, { build, emitError, transpileOnly, pr return pipeline; } -export function transpileTask(src: string, out: string, esbuild: boolean): task.StreamTask { +export function transpileTask(src: string, out: string, esbuild?: boolean): task.StreamTask { const task = () => { - const transpile = createCompile(src, { build: false, emitError: true, transpileOnly: { esbuild }, preserveEnglish: false }); + const transpile = createCompile(src, { build: false, emitError: true, transpileOnly: { esbuild: !!esbuild }, preserveEnglish: false }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); return srcPipe @@ -301,7 +301,7 @@ function generateApiProposalNames() { const proposalName = match[1]; - const contents = f.contents.toString('utf8'); + const contents = f.contents!.toString('utf8'); const versionMatch = versionPattern.exec(contents); const version = versionMatch ? versionMatch[1] : undefined; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index b900802ed6a..1a55acc52cf 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -38,7 +38,7 @@ function minifyExtensionResources(input: Stream): Stream { .pipe(buffer()) .pipe(es.mapSync((f: File) => { const errors: jsoncParser.ParseError[] = []; - const value = jsoncParser.parse(f.contents.toString('utf8'), errors, { allowTrailingComma: true }); + const value = jsoncParser.parse(f.contents!.toString('utf8'), errors, { allowTrailingComma: true }); if (errors.length === 0) { // file parsed OK => just stringify to drop whitespace and comments f.contents = Buffer.from(JSON.stringify(value)); @@ -54,7 +54,7 @@ function updateExtensionPackageJSON(input: Stream, update: (data: any) => any): .pipe(packageJsonFilter) .pipe(buffer()) .pipe(es.mapSync((f: File) => { - const data = JSON.parse(f.contents.toString('utf8')); + const data = JSON.parse(f.contents!.toString('utf8')); f.contents = Buffer.from(JSON.stringify(update(data))); return f; })) diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index 96468033719..13cefe51dad 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -389,7 +389,7 @@ export function processNlsFiles(opts: { out: string; fileHeader: string; languag const fileName = path.basename(file.path); if (fileName === 'nls.keys.json') { try { - const contents = file.contents.toString('utf8'); + const contents = file.contents!.toString('utf8'); const json = JSON.parse(contents); if (NLSKeysFormat.is(json)) { processCoreBundleFormat(file.base, opts.fileHeader, opts.languages, json, this); @@ -653,7 +653,7 @@ export function createXlfFilesForIsl(): ThroughStream { keys: string[] = [], messages: string[] = []; - const model = new TextModel(file.contents.toString()); + const model = new TextModel(file.contents!.toString()); let inMessageSection = false; model.lines.forEach(line => { if (line.length === 0) { @@ -752,7 +752,7 @@ export function prepareI18nPackFiles(resultingTranslationPaths: TranslationPath[ if (EXTERNAL_EXTENSIONS.find(e => e === resource)) { project = extensionsProject; } - const contents = xlf.contents.toString(); + const contents = xlf.contents!.toString(); log(`Found ${project}: ${resource}`); const parsePromise = getL10nFilesFromXlf(contents); parsePromises.push(parsePromise); @@ -808,7 +808,7 @@ export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup): return through(function (this: ThroughStream, xlf: File) { const stream = this; - const parsePromise = XLF.parse(xlf.contents.toString()); + const parsePromise = XLF.parse(xlf.contents!.toString()); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { diff --git a/build/lib/inlineMeta.ts b/build/lib/inlineMeta.ts index 2a0db13d06e..530e1ec30ea 100644 --- a/build/lib/inlineMeta.ts +++ b/build/lib/inlineMeta.ts @@ -26,7 +26,7 @@ const packageJsonMarkerId = 'BUILD_INSERT_PACKAGE_CONFIGURATION'; export function inlineMeta(result: NodeJS.ReadWriteStream, ctx: IInlineMetaContext): NodeJS.ReadWriteStream { return result.pipe(es.through(function (file: File) { if (matchesFile(file, ctx)) { - let content = file.contents.toString(); + let content = file.contents!.toString(); let markerFound = false; const packageMarker = `${packageJsonMarkerId}:"${packageJsonMarkerId}"`; // this needs to be the format after esbuild has processed the file (e.g. double quotes) diff --git a/build/lib/nls.js b/build/lib/nls.js index b2fbf88981c..492dbdae8ce 100644 --- a/build/lib/nls.js +++ b/build/lib/nls.js @@ -182,7 +182,7 @@ var _nls; .map(d => d.importClause.namedBindings.name) .concat(importEqualsDeclarations.map(d => d.name)) // find read-only references to `nls` - .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) + .map(n => service.getReferencesAtPosition(filename, n.pos + 1) ?? []) .flatten() .filter(r => !r.isWriteAccess) // find the deepest call expressions AST nodes that contain those references @@ -200,13 +200,13 @@ var _nls; // `localize` read-only references const localizeReferences = allLocalizeImportDeclarations .filter(d => d.name.getText() === functionName) - .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) + .map(n => service.getReferencesAtPosition(filename, n.pos + 1) ?? []) .flatten() .filter(r => !r.isWriteAccess); // custom named `localize` read-only references const namedLocalizeReferences = allLocalizeImportDeclarations .filter(d => d.propertyName && d.propertyName.getText() === functionName) - .map(n => service.getReferencesAtPosition(filename, n.name.pos + 1)) + .map(n => service.getReferencesAtPosition(filename, n.name.pos + 1) ?? []) .flatten() .filter(r => !r.isWriteAccess); // find the deepest call expressions AST nodes that contain those references diff --git a/build/lib/nls.ts b/build/lib/nls.ts index ef2afc5d7c8..a21102b0ccc 100644 --- a/build/lib/nls.ts +++ b/build/lib/nls.ts @@ -11,9 +11,7 @@ import sm from 'source-map'; import path from 'path'; import sort from 'gulp-sort'; -declare class FileSourceMap extends File { - public sourceMap: sm.RawSourceMap; -} +type FileSourceMap = File & { sourceMap: sm.RawSourceMap }; enum CollectStepResult { Yes, @@ -248,7 +246,7 @@ module _nls { .concat(importEqualsDeclarations.map(d => d.name)) // find read-only references to `nls` - .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) + .map(n => service.getReferencesAtPosition(filename, n.pos + 1) ?? []) .flatten() .filter(r => !r.isWriteAccess) @@ -270,14 +268,14 @@ module _nls { // `localize` read-only references const localizeReferences = allLocalizeImportDeclarations .filter(d => d.name.getText() === functionName) - .map(n => service.getReferencesAtPosition(filename, n.pos + 1)) + .map(n => service.getReferencesAtPosition(filename, n.pos + 1) ?? []) .flatten() .filter(r => !r.isWriteAccess); // custom named `localize` read-only references const namedLocalizeReferences = allLocalizeImportDeclarations .filter(d => d.propertyName && d.propertyName.getText() === functionName) - .map(n => service.getReferencesAtPosition(filename, n.name.pos + 1)) + .map(n => service.getReferencesAtPosition(filename, n.name.pos + 1) ?? []) .flatten() .filter(r => !r.isWriteAccess); @@ -504,7 +502,7 @@ module _nls { const { javascript, sourcemap, nlsKeys, nlsMessages } = patch( ts, typescript, - javascriptFile.contents.toString(), + javascriptFile.contents!.toString(), (javascriptFile).sourceMap, options ); diff --git a/build/lib/typings/github-releases.d.ts b/build/lib/typings/github-releases.d.ts deleted file mode 100644 index 5706a86b5e4..00000000000 --- a/build/lib/typings/github-releases.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'github-releases' { - -} \ No newline at end of file diff --git a/build/lib/typings/gulp-flatmap.d.ts b/build/lib/typings/gulp-flatmap.d.ts deleted file mode 100644 index c99232c61cc..00000000000 --- a/build/lib/typings/gulp-flatmap.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare module 'gulp-flatmap' { - import File = require('vinyl'); - function f(fn:(stream:NodeJS.ReadWriteStream, file:File)=>NodeJS.ReadWriteStream): NodeJS.ReadWriteStream; - - /** - * This is required as per: - * https://github.com/microsoft/TypeScript/issues/5073 - */ - namespace f {} - - export = f; -} diff --git a/build/lib/typings/lazy.js.d.ts b/build/lib/typings/lazy.js.d.ts deleted file mode 100644 index f69924b4b1c..00000000000 --- a/build/lib/typings/lazy.js.d.ts +++ /dev/null @@ -1,276 +0,0 @@ -// Type definitions for Lazy.js 0.3.2 -// Project: https://github.com/dtao/lazy.js/ -// Definitions by: Bart van der Schoor -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare function Lazy(value: string): Lazy.StringLikeSequence; -declare function Lazy(value: T[]): Lazy.ArrayLikeSequence; -declare function Lazy(value: any[]): Lazy.ArrayLikeSequence; -declare function Lazy(value: Object): Lazy.ObjectLikeSequence; -declare function Lazy(value: Object): Lazy.ObjectLikeSequence; - -declare module Lazy { - function strict(): StrictLazy; - function generate(generatorFn: GeneratorCallback, length?: number): GeneratedSequence; - function range(to: number): GeneratedSequence; - function range(from: number, to: number, step?: number): GeneratedSequence; - function repeat(value: T, count?: number): GeneratedSequence; - function on(eventType: string): Sequence; - function readFile(path: string): StringLikeSequence; - function makeHttpRequest(path: string): StringLikeSequence; - - interface StrictLazy { - (value: string): StringLikeSequence; - (value: T[]): ArrayLikeSequence; - (value: any[]): ArrayLikeSequence; - (value: Object): ObjectLikeSequence; - (value: Object): ObjectLikeSequence; - strict(): StrictLazy; - generate(generatorFn: GeneratorCallback, length?: number): GeneratedSequence; - range(to: number): GeneratedSequence; - range(from: number, to: number, step?: number): GeneratedSequence; - repeat(value: T, count?: number): GeneratedSequence; - on(eventType: string): Sequence; - readFile(path: string): StringLikeSequence; - makeHttpRequest(path: string): StringLikeSequence; - } - - interface ArrayLike { - length: number; - [index: number]: T; - } - - interface Callback { - (): void; - } - - interface ErrorCallback { - (error: any): void; - } - - interface ValueCallback { - (value: T): void; - } - - interface GetKeyCallback { - (value: T): string; - } - - interface TestCallback { - (value: T): boolean; - } - - interface MapCallback { - (value: T): U; - } - - interface MapStringCallback { - (value: string): string; - } - - interface NumberCallback { - (value: T): number; - } - - interface MemoCallback { - (memo: U, value: T): U; - } - - interface GeneratorCallback { - (index: number): T; - } - - interface CompareCallback { - (x: any, y: any): number; - } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - interface Iterator { - new(sequence: Sequence): Iterator; - current(): T; - moveNext(): boolean; - } - - interface GeneratedSequence extends Sequence { - new(generatorFn: GeneratorCallback, length: number): GeneratedSequence; - length(): number; - } - - interface AsyncSequence extends SequenceBase { - each(callback: ValueCallback): AsyncHandle; - } - - interface AsyncHandle { - cancel(): void; - onComplete(callback: Callback): void; - onError(callback: ErrorCallback): void; - } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module Sequence { - function define(methodName: string[], overrides: Object): Function; - } - - interface Sequence extends SequenceBase { - each(eachFn: ValueCallback): Sequence; - } - - interface ArraySequence extends SequenceBase { - flatten(): Sequence; - } - - interface SequenceBase extends SequenceBaser { - first(): any; - first(count: number): Sequence; - indexOf(value: any, startIndex?: number): Sequence; - - last(): any; - last(count: number): Sequence; - lastIndexOf(value: any): Sequence; - - reverse(): Sequence; - } - - interface SequenceBaser { - // TODO improve define() (needs ugly overload) - async(interval: number): AsyncSequence; - chunk(size: number): Sequence; - compact(): Sequence; - concat(var_args: T[]): Sequence; - concat(sequence: Sequence): Sequence; - consecutive(length: number): Sequence; - contains(value: T): boolean; - countBy(keyFn: GetKeyCallback): ObjectLikeSequence; - countBy(propertyName: string): ObjectLikeSequence; - dropWhile(predicateFn: TestCallback): Sequence; - every(predicateFn: TestCallback): boolean; - filter(predicateFn: TestCallback): Sequence; - find(predicateFn: TestCallback): Sequence; - findWhere(properties: Object): Sequence; - - groupBy(keyFn: GetKeyCallback): ObjectLikeSequence; - initial(count?: number): Sequence; - intersection(var_args: T[]): Sequence; - invoke(methodName: string): Sequence; - isEmpty(): boolean; - join(delimiter?: string): string; - map(mapFn: MapCallback): ArraySequence; - map(mapFn: MapCallback): Sequence; - - // TODO: vscode addition to workaround strict null errors - flatten(): Sequence; - - max(valueFn?: NumberCallback): T; - min(valueFn?: NumberCallback): T; - none(valueFn?: TestCallback): boolean; - pluck(propertyName: string): Sequence; - reduce(aggregatorFn: MemoCallback, memo?: U): U; - reduceRight(aggregatorFn: MemoCallback, memo: U): U; - reject(predicateFn: TestCallback): Sequence; - rest(count?: number): Sequence; - shuffle(): Sequence; - some(predicateFn?: TestCallback): boolean; - sort(sortFn?: CompareCallback, descending?: boolean): Sequence; - sortBy(sortFn: string, descending?: boolean): Sequence; - sortBy(sortFn: NumberCallback, descending?: boolean): Sequence; - sortedIndex(value: T): Sequence; - size(): number; - sum(valueFn?: NumberCallback): Sequence; - takeWhile(predicateFn: TestCallback): Sequence; - union(var_args: T[]): Sequence; - uniq(): Sequence; - where(properties: Object): Sequence; - without(...var_args: T[]): Sequence; - without(var_args: T[]): Sequence; - zip(var_args: T[]): ArraySequence; - - toArray(): T[]; - toObject(): Object; - } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module ArrayLikeSequence { - function define(methodName: string[], overrides: Object): Function; - } - - interface ArrayLikeSequence extends Sequence { - // define()X; - concat(var_args: T[]): ArrayLikeSequence; - concat(sequence: Sequence): Sequence; - first(count?: number): ArrayLikeSequence; - get(index: number): T; - length(): number; - map(mapFn: MapCallback): ArraySequence; - map(mapFn: MapCallback): ArrayLikeSequence; - pop(): ArrayLikeSequence; - rest(count?: number): ArrayLikeSequence; - reverse(): ArrayLikeSequence; - shift(): ArrayLikeSequence; - slice(begin: number, end?: number): ArrayLikeSequence; - } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module ObjectLikeSequence { - function define(methodName: string[], overrides: Object): Function; - } - - interface ObjectLikeSequence extends Sequence { - assign(other: Object): ObjectLikeSequence; - // throws error - //async(): X; - defaults(defaults: Object): ObjectLikeSequence; - functions(): Sequence; - get(property: string): ObjectLikeSequence; - invert(): ObjectLikeSequence; - keys(): Sequence; - omit(properties: string[]): ObjectLikeSequence; - pairs(): Sequence; - pick(properties: string[]): ObjectLikeSequence; - toArray(): T[]; - toObject(): Object; - values(): Sequence; - } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module StringLikeSequence { - function define(methodName: string[], overrides: Object): Function; - } - - interface StringLikeSequence extends SequenceBaser { - charAt(index: number): string; - charCodeAt(index: number): number; - contains(value: string): boolean; - endsWith(suffix: string): boolean; - - first(): string; - first(count: number): StringLikeSequence; - - indexOf(substring: string, startIndex?: number): number; - - last(): string; - last(count: number): StringLikeSequence; - - lastIndexOf(substring: string, startIndex?: number): number; - mapString(mapFn: MapStringCallback): StringLikeSequence; - match(pattern: RegExp): StringLikeSequence; - reverse(): StringLikeSequence; - - split(delimiter: string): StringLikeSequence; - split(delimiter: RegExp): StringLikeSequence; - - startsWith(prefix: string): boolean; - substring(start: number, stop?: number): StringLikeSequence; - toLowerCase(): StringLikeSequence; - toUpperCase(): StringLikeSequence; - } -} - -declare module 'lazy.js' { - export = Lazy; -} - diff --git a/build/lib/typings/vinyl.d.ts b/build/lib/typings/vinyl.d.ts deleted file mode 100644 index 5062c5154f6..00000000000 --- a/build/lib/typings/vinyl.d.ts +++ /dev/null @@ -1,135 +0,0 @@ -// Type definitions for vinyl 0.4.3 -// Project: https://github.com/wearefractal/vinyl -// Definitions by: vvakame , jedmao -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -declare module "vinyl" { - - import fs = require("fs"); - - /** - * A virtual file format. - */ - class File { - constructor(options?: { - /** - * Default: process.cwd() - */ - cwd?: string; - /** - * Used for relative pathing. Typically where a glob starts. - */ - base?: string; - /** - * Full path to the file. - */ - path?: string; - /** - * Path history. Has no effect if options.path is passed. - */ - history?: string[]; - /** - * The result of an fs.stat call. See fs.Stats for more information. - */ - stat?: fs.Stats; - /** - * File contents. - * Type: Buffer, Stream, or null - */ - contents?: Buffer | NodeJS.ReadWriteStream; - }); - - /** - * Default: process.cwd() - */ - public cwd: string; - /** - * Used for relative pathing. Typically where a glob starts. - */ - public base: string; - /** - * Gets and sets the basename of `file.path`. - * - * Throws when `file.path` is not set. - * - * Example: - * - * ```js - * var file = new File({ - * cwd: '/', - * base: '/test/', - * path: '/test/file.js' - * }); - * - * console.log(file.basename); // file.js - * - * file.basename = 'file.txt'; - * - * console.log(file.basename); // file.txt - * console.log(file.path); // /test/file.txt - * ``` - */ - basename: string; - /** - * Full path to the file. - */ - public path: string; - public stat: fs.Stats; - /** - * Type: Buffer|Stream|null (Default: null) - */ - public contents: Buffer | NodeJS.ReadableStream; - /** - * Returns path.relative for the file base and file path. - * Example: - * var file = new File({ - * cwd: "/", - * base: "/test/", - * path: "/test/file.js" - * }); - * console.log(file.relative); // file.js - */ - public relative: string; - - public isBuffer(): boolean; - - public isStream(): boolean; - - public isNull(): boolean; - - public isDirectory(): boolean; - - /** - * Returns a new File object with all attributes cloned. Custom attributes are deep-cloned. - */ - public clone(opts?: { contents?: boolean }): File; - - /** - * If file.contents is a Buffer, it will write it to the stream. - * If file.contents is a Stream, it will pipe it to the stream. - * If file.contents is null, it will do nothing. - */ - public pipe( - stream: T, - opts?: { - /** - * If false, the destination stream will not be ended (same as node core). - */ - end?: boolean; - }): T; - - /** - * Returns a pretty String interpretation of the File. Useful for console.log. - */ - public inspect(): string; - } - - /** - * This is required as per: - * https://github.com/microsoft/TypeScript/issues/5073 - */ - namespace File { } - - export = File; - -} diff --git a/build/lib/util.ts b/build/lib/util.ts index ad81730b3de..49313429da9 100644 --- a/build/lib/util.ts +++ b/build/lib/util.ts @@ -131,7 +131,7 @@ export function setExecutableBit(pattern?: string | string[]): NodeJS.ReadWriteS if (!f.stat) { f.stat = { isFile() { return true; } } as any; } - f.stat.mode = /* 100755 */ 33261; + f.stat!.mode = /* 100755 */ 33261; return f; }); @@ -185,9 +185,7 @@ export function cleanNodeModules(rulePath: string): NodeJS.ReadWriteStream { return es.duplex(input, output); } -declare class FileSourceMap extends VinylFile { - public sourceMap: sm.RawSourceMap; -} +type FileSourceMap = VinylFile & { sourceMap: sm.RawSourceMap }; export function loadSourcemaps(): NodeJS.ReadWriteStream { const input = es.through(); diff --git a/build/package-lock.json b/build/package-lock.json index 55607f7de71..663a0ea6f13 100644 --- a/build/package-lock.json +++ b/build/package-lock.json @@ -25,20 +25,26 @@ "@types/glob": "^7.1.1", "@types/gulp": "^4.0.17", "@types/gulp-filter": "^3.0.32", + "@types/gulp-flatmap": "^1.0.0", "@types/gulp-gzip": "^0.0.31", "@types/gulp-json-editor": "^2.2.31", + "@types/gulp-plumber": "^0.0.37", "@types/gulp-rename": "^0.0.33", + "@types/gulp-replace": "^0.0.31", "@types/gulp-sort": "^2.0.4", "@types/gulp-sourcemaps": "^0.0.32", "@types/jws": "^3.2.10", + "@types/lazy.js": "^0.5.9", "@types/mime": "0.0.29", "@types/minimatch": "^3.0.3", "@types/minimist": "^1.2.1", "@types/node": "22.x", + "@types/p-all": "^1.0.0", "@types/pump": "^1.0.1", "@types/rimraf": "^2.0.4", "@types/through": "^0.0.29", "@types/through2": "^2.0.36", + "@types/vinyl": "^2.0.12", "@types/workerpool": "^6.4.0", "@types/xml2js": "0.0.33", "@vscode/iconv-lite-umd": "0.7.0", @@ -1129,6 +1135,17 @@ "@types/vinyl": "*" } }, + "node_modules/@types/gulp-flatmap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/gulp-flatmap/-/gulp-flatmap-1.0.0.tgz", + "integrity": "sha512-GTv0a9BxhbWYkxaPDCqnZFI13pXUUpJ90hBWkhGOQQ76qDDtHWugr0+IEiTEc0KYS0bOs80YszZE7WFNA5ndfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/vinyl": "*" + } + }, "node_modules/@types/gulp-gzip": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/@types/gulp-gzip/-/gulp-gzip-0.0.31.tgz", @@ -1148,6 +1165,16 @@ "@types/node": "*" } }, + "node_modules/@types/gulp-plumber": { + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/@types/gulp-plumber/-/gulp-plumber-0.0.37.tgz", + "integrity": "sha512-U1vFhhwDepAWmJ1ZVl6p+uwk/+rAs8+QLTRlrMLMQQ7KeqPPCvD5vy6JHMeqXwnxMSlbboa2PXQqoMg+ljZIJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/gulp-rename": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/gulp-rename/-/gulp-rename-0.0.33.tgz", @@ -1157,6 +1184,16 @@ "@types/node": "*" } }, + "node_modules/@types/gulp-replace": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/@types/gulp-replace/-/gulp-replace-0.0.31.tgz", + "integrity": "sha512-dbgQ1u0N9ShXrzahBgQfMSu6qUh8nlTLt7whhQ0S0sEUHhV3scysppJ1UX0fl53PJENgAL99ueykddyrCaDt7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/gulp-sort": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/gulp-sort/-/gulp-sort-2.0.4.tgz", @@ -1219,6 +1256,13 @@ "@types/node": "*" } }, + "node_modules/@types/lazy.js": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@types/lazy.js/-/lazy.js-0.5.9.tgz", + "integrity": "sha512-oO7oF31unBSr3M4yshbgie/PP5VLQTWvopHQqD0OYIQ1ItFHlxBJBBYAn6gOiRK4elQKF0s/nJ45wIJziU4MqQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mime": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-0.0.29.tgz", @@ -1253,6 +1297,13 @@ "undici-types": "~6.20.0" } }, + "node_modules/@types/p-all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/p-all/-/p-all-1.0.0.tgz", + "integrity": "sha512-ZaM7VBS9kzAcDPB7YkoQWYxujUQyblUsjBmVaSO0igkoO7/Sus+cIoriD8/8RPpCOFnyPU1SfDDB5hH+i4S9Eg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/pump": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/pump/-/pump-1.0.1.tgz", @@ -1321,6 +1372,7 @@ "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.12.tgz", "integrity": "sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==", "dev": true, + "license": "MIT", "dependencies": { "@types/expect": "^1.20.4", "@types/node": "*" diff --git a/build/package.json b/build/package.json index 9477b8403ca..54ada234d79 100644 --- a/build/package.json +++ b/build/package.json @@ -19,20 +19,26 @@ "@types/glob": "^7.1.1", "@types/gulp": "^4.0.17", "@types/gulp-filter": "^3.0.32", + "@types/gulp-flatmap": "^1.0.0", "@types/gulp-gzip": "^0.0.31", "@types/gulp-json-editor": "^2.2.31", + "@types/gulp-plumber": "^0.0.37", "@types/gulp-rename": "^0.0.33", + "@types/gulp-replace": "^0.0.31", "@types/gulp-sort": "^2.0.4", "@types/gulp-sourcemaps": "^0.0.32", "@types/jws": "^3.2.10", + "@types/lazy.js": "^0.5.9", "@types/mime": "0.0.29", "@types/minimatch": "^3.0.3", "@types/minimist": "^1.2.1", "@types/node": "22.x", + "@types/p-all": "^1.0.0", "@types/pump": "^1.0.1", "@types/rimraf": "^2.0.4", "@types/through": "^0.0.29", "@types/through2": "^2.0.36", + "@types/vinyl": "^2.0.12", "@types/workerpool": "^6.4.0", "@types/xml2js": "0.0.33", "@vscode/iconv-lite-umd": "0.7.0", diff --git a/build/setup-npm-registry.js b/build/setup-npm-registry.js index 24c850dbb84..5d637f97632 100644 --- a/build/setup-npm-registry.js +++ b/build/setup-npm-registry.js @@ -2,12 +2,17 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - +// @ts-check 'use strict'; const fs = require('fs').promises; const path = require('path'); +/** + * @param {string} dir + * + * @returns {AsyncGenerator} + */ async function* getPackageLockFiles(dir) { const files = await fs.readdir(dir); @@ -23,12 +28,20 @@ async function* getPackageLockFiles(dir) { } } +/** + * @param {string} url + * @param {string} file + */ async function setup(url, file) { let contents = await fs.readFile(file, 'utf8'); contents = contents.replace(/https:\/\/registry\.[^.]+\.com\//g, url); await fs.writeFile(file, contents); } +/** + * @param {string} url + * @param {string} dir + */ async function main(url, dir) { const root = dir ?? process.cwd(); diff --git a/build/stylelint.js b/build/stylelint.js index 5b1668ea2e4..03c1611c4e0 100644 --- a/build/stylelint.js +++ b/build/stylelint.js @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +// @ts-check const es = require('event-stream'); const vfs = require('vinyl-fs'); @@ -10,11 +11,16 @@ const { getVariableNameValidator } = require('./lib/stylelint/validateVariableNa module.exports = gulpstylelint; -/** use regex on lines */ +/** + * use regex on lines + * + * @param {function(string, boolean):void} reporter + */ function gulpstylelint(reporter) { const variableValidator = getVariableNameValidator(); let errorCount = 0; return es.through(function (file) { + /** @type {string[]} */ const lines = file.__lines || file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; diff --git a/build/tsconfig.build.json b/build/tsconfig.build.json index 4534420208f..dc3305690bc 100644 --- a/build/tsconfig.build.json +++ b/build/tsconfig.build.json @@ -8,8 +8,5 @@ }, "include": [ "**/*.ts" - ], - "exclude": [ - "lib/eslint-plugin-vscode/**/*" ] }