From f0e7fe3775a9d79f875a10387882a14b3f1bf7aa Mon Sep 17 00:00:00 2001 From: Matt Bierner <12821956+mjbvz@users.noreply.github.com> Date: Fri, 21 Nov 2025 09:20:38 -0800 Subject: [PATCH] Convert a few more build scripts to TypeScript For #277526 --- .../product-build-alpine-node-modules.yml | 2 +- .../alpine/product-build-alpine.yml | 2 +- .../darwin/product-build-darwin-cli-sign.yml | 2 +- .../product-build-darwin-node-modules.yml | 2 +- .../darwin/product-build-darwin-universal.yml | 2 +- .../steps/product-build-darwin-compile.yml | 2 +- .../linux/product-build-linux-cli.yml | 2 +- .../product-build-linux-node-modules.yml | 2 +- .../steps/product-build-linux-compile.yml | 2 +- build/azure-pipelines/product-compile.yml | 2 +- .../product-npm-package-validate.yml | 2 +- .../web/product-build-web-node-modules.yml | 2 +- .../azure-pipelines/web/product-build-web.yml | 2 +- .../win32/product-build-win32-cli-sign.yml | 2 +- .../product-build-win32-node-modules.yml | 2 +- .../azure-pipelines/win32/sdl-scan-win32.yml | 2 +- .../steps/product-build-win32-compile.yml | 2 +- build/{buildfile.js => buildfile.ts} | 9 +- build/{eslint.mjs => eslint.ts} | 10 +- build/{filters.js => filters.ts} | 36 ++++--- build/{gulp-eslint.js => gulp-eslint.ts} | 35 ++++--- build/gulpfile.hygiene.mjs | 2 +- build/gulpfile.reh.mjs | 2 +- build/gulpfile.vscode.mjs | 2 +- build/gulpfile.vscode.web.mjs | 2 +- build/{hygiene.mjs => hygiene.ts} | 98 +++++++++---------- build/lib/mangle/index.ts | 2 +- build/lib/{node.js => node.ts} | 6 +- ...-npm-registry.js => setup-npm-registry.ts} | 18 ++-- build/{stylelint.mjs => stylelint.ts} | 31 +++--- package.json | 6 +- scripts/code-server.sh | 2 +- scripts/code-web.bat | 2 +- scripts/code-web.sh | 4 +- 34 files changed, 146 insertions(+), 155 deletions(-) rename build/{buildfile.js => buildfile.ts} (96%) rename build/{eslint.mjs => eslint.ts} (80%) rename build/{filters.js => filters.ts} (94%) rename build/{gulp-eslint.js => gulp-eslint.ts} (72%) rename build/{hygiene.mjs => hygiene.ts} (74%) rename build/lib/{node.js => node.ts} (85%) rename build/{setup-npm-registry.js => setup-npm-registry.ts} (75%) rename build/{stylelint.mjs => stylelint.ts} (78%) diff --git a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml index f1b9fceac83..cc53000a15c 100644 --- a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml +++ b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml @@ -29,7 +29,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 5c33e758802..5c5714e9d5b 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -73,7 +73,7 @@ jobs: - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml index c26f2ad25c8..94eee5e476c 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-cli-sign.yml @@ -41,7 +41,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.js $NPM_REGISTRY build + - script: node build/setup-npm-registry.ts $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml index 8b3f9c9305a..19b38a60952 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml @@ -28,7 +28,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index 5938c13dde2..81bff1ae5f6 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -31,7 +31,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - - script: node build/setup-npm-registry.js $NPM_REGISTRY build + - script: node build/setup-npm-registry.ts $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml index 50ef7bd6158..1d38413bde4 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml @@ -39,7 +39,7 @@ steps: - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/linux/product-build-linux-cli.yml b/build/azure-pipelines/linux/product-build-linux-cli.yml index 9052a29e18e..ef160c2cc38 100644 --- a/build/azure-pipelines/linux/product-build-linux-cli.yml +++ b/build/azure-pipelines/linux/product-build-linux-cli.yml @@ -51,7 +51,7 @@ jobs: tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.11.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - - script: node build/setup-npm-registry.js $NPM_REGISTRY build + - script: node build/setup-npm-registry.ts $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/linux/product-build-linux-node-modules.yml b/build/azure-pipelines/linux/product-build-linux-node-modules.yml index cfbdae8d55f..16cf3e8a2f6 100644 --- a/build/azure-pipelines/linux/product-build-linux-node-modules.yml +++ b/build/azure-pipelines/linux/product-build-linux-node-modules.yml @@ -48,7 +48,7 @@ jobs: sudo service xvfb start displayName: Setup system services - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml index 7548c0498d0..bf15e902dc1 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml @@ -61,7 +61,7 @@ steps: sudo service xvfb start displayName: Setup system services - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index caa539c67cb..7990c3b545d 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -29,7 +29,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/product-npm-package-validate.yml b/build/azure-pipelines/product-npm-package-validate.yml index 4979c96edc5..d702ddfef5e 100644 --- a/build/azure-pipelines/product-npm-package-validate.yml +++ b/build/azure-pipelines/product-npm-package-validate.yml @@ -47,7 +47,7 @@ jobs: fi displayName: Check if package files were modified - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'), eq(variables['SHOULD_VALIDATE'], 'true')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/web/product-build-web-node-modules.yml b/build/azure-pipelines/web/product-build-web-node-modules.yml index 6a98a9f79ad..75a0cc6cd6e 100644 --- a/build/azure-pipelines/web/product-build-web-node-modules.yml +++ b/build/azure-pipelines/web/product-build-web-node-modules.yml @@ -22,7 +22,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 74b84fc9fef..1d5dd9798e7 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -42,7 +42,7 @@ jobs: - script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz displayName: Extract compilation output - - script: node build/setup-npm-registry.js $NPM_REGISTRY + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/product-build-win32-cli-sign.yml b/build/azure-pipelines/win32/product-build-win32-cli-sign.yml index 2b6fe1439b9..fa1328d99e2 100644 --- a/build/azure-pipelines/win32/product-build-win32-cli-sign.yml +++ b/build/azure-pipelines/win32/product-build-win32-cli-sign.yml @@ -42,7 +42,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY build + - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/product-build-win32-node-modules.yml b/build/azure-pipelines/win32/product-build-win32-node-modules.yml index f59cb84181f..6780073f57a 100644 --- a/build/azure-pipelines/win32/product-build-win32-node-modules.yml +++ b/build/azure-pipelines/win32/product-build-win32-node-modules.yml @@ -33,7 +33,7 @@ jobs: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY + - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/sdl-scan-win32.yml b/build/azure-pipelines/win32/sdl-scan-win32.yml index f7d8849dbcb..96c42ac65c3 100644 --- a/build/azure-pipelines/win32/sdl-scan-win32.yml +++ b/build/azure-pipelines/win32/sdl-scan-win32.yml @@ -26,7 +26,7 @@ steps: KeyVaultName: vscode-build-secrets SecretsFilter: "github-distro-mixin-password" - - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY + - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml index fa5acee1c6c..950846aa01c 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml @@ -49,7 +49,7 @@ steps: archiveFilePatterns: "$(Build.ArtifactStagingDirectory)/compilation.tar.gz" cleanDestinationFolder: false - - powershell: node build/setup-npm-registry.js $env:NPM_REGISTRY + - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/buildfile.js b/build/buildfile.ts similarity index 96% rename from build/buildfile.js rename to build/buildfile.ts index 9b5d07dec45..99a9832f404 100644 --- a/build/buildfile.js +++ b/build/buildfile.ts @@ -2,13 +2,10 @@ * 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 - * @returns {import('./lib/bundle.js').IEntryPoint} - */ -export function createModuleDescription(name) { +import type { IEntryPoint } from './lib/bundle.ts'; + +function createModuleDescription(name: string): IEntryPoint { return { name }; diff --git a/build/eslint.mjs b/build/eslint.ts similarity index 80% rename from build/eslint.mjs rename to build/eslint.ts index 228a3fd9d8c..a2ef396a16c 100644 --- a/build/eslint.mjs +++ b/build/eslint.ts @@ -2,15 +2,15 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// @ts-check + import eventStream from 'event-stream'; import vfs from 'vinyl-fs'; -import { eslintFilter } from './filters.js'; -import gulpEslint from './gulp-eslint.js'; +import { eslintFilter } from './filters.ts'; +import gulpEslint from './gulp-eslint.ts'; -function eslint() { +function eslint(): NodeJS.ReadWriteStream { return vfs - .src(eslintFilter, { base: '.', follow: true, allowEmpty: true }) + .src(Array.from(eslintFilter), { base: '.', follow: true, allowEmpty: true }) .pipe( gulpEslint((results) => { if (results.warningCount > 0 || results.errorCount > 0) { diff --git a/build/filters.js b/build/filters.ts similarity index 94% rename from build/filters.js rename to build/filters.ts index 7161395cd42..04c72e27cbc 100644 --- a/build/filters.js +++ b/build/filters.ts @@ -2,7 +2,9 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// @ts-check + +import { readFileSync } from 'fs'; +import { join } from 'path'; /** * Hygiene works by creating cascading subsets of all our files and @@ -13,11 +15,7 @@ * all ⊃ eol ⊇ indentation ⊃ copyright ⊃ typescript */ -import { readFileSync } from 'fs'; -import { join } from 'path'; - - -export const all = [ +export const all = Object.freeze([ '*', 'build/**/*', 'extensions/**/*', @@ -30,9 +28,9 @@ export const all = [ '!test/**/out/**', '!**/node_modules/**', '!**/*.js.map', -]; +]); -export const unicodeFilter = [ +export const unicodeFilter = Object.freeze([ '**', '!**/ThirdPartyNotices.txt', @@ -67,9 +65,9 @@ export const unicodeFilter = [ '!src/vs/base/browser/dompurify/**', '!src/vs/workbench/services/keybinding/browser/keyboardLayouts/**', '!src/vs/workbench/contrib/terminal/common/scripts/psreadline/**', -]; +]); -export const indentationFilter = [ +export const indentationFilter = Object.freeze([ '**', // except specific files @@ -150,9 +148,9 @@ export const indentationFilter = [ '!extensions/ipynb/notebook-out/**', '!extensions/notebook-renderers/renderer-out/*.js', '!extensions/simple-browser/media/*.js', -]; +]); -export const copyrightFilter = [ +export const copyrightFilter = Object.freeze([ '**', '!**/*.desktop', '!**/*.json', @@ -192,9 +190,9 @@ export const copyrightFilter = [ '!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/*/server/bin/*', '!src/vs/workbench/contrib/terminal/common/scripts/psreadline/**', -]; +]); -export const tsFormattingFilter = [ +export const tsFormattingFilter = Object.freeze([ 'src/**/*.ts', 'test/**/*.ts', 'extensions/**/*.ts', @@ -211,9 +209,9 @@ export const tsFormattingFilter = [ '!extensions/html-language-features/server/lib/jquery.d.ts', '!extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts', '!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts', -]; +]); -export const eslintFilter = [ +export const eslintFilter = Object.freeze([ '**/*.js', '**/*.cjs', '**/*.mjs', @@ -224,8 +222,8 @@ export const eslintFilter = [ .split(/\r\n|\n/) .filter(line => line && !line.startsWith('#')) .map(line => line.startsWith('!') ? line.slice(1) : `!${line}`) -]; +]); -export const stylelintFilter = [ +export const stylelintFilter = Object.freeze([ 'src/**/*.css' -]; +]); diff --git a/build/gulp-eslint.js b/build/gulp-eslint.ts similarity index 72% rename from build/gulp-eslint.js rename to build/gulp-eslint.ts index 9e543741de3..1e953cdba7b 100644 --- a/build/gulp-eslint.js +++ b/build/gulp-eslint.ts @@ -2,28 +2,28 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ + import { ESLint } from 'eslint'; import fancyLog from 'fancy-log'; import { relative } from 'path'; -import Stream, { Transform } from 'stream'; +import { Transform, type TransformOptions } from 'stream'; -/** - * @typedef {ESLint.LintResult[] & { errorCount: number, warningCount: number}} ESLintResults - */ +interface ESLintResults extends Array { + errorCount: number; + warningCount: number; +} -/** - * @param {(results: ESLintResults) => void} action - A function to handle all ESLint results - */ -export default function eslint(action) { +interface EslintAction { + (results: ESLintResults): void; +} + +export default function eslint(action: EslintAction) { const linter = new ESLint({}); const formatter = linter.loadFormatter('compact'); - /** @type {ESLintResults} results */ - const results = []; - results.errorCount = 0; - results.warningCount = 0; + const results: ESLintResults = Object.assign([], { errorCount: 0, warningCount: 0 }); - return transform( + return createTransform( async (file, _enc, cb) => { const filePath = relative(process.cwd(), file.path); @@ -68,11 +68,10 @@ export default function eslint(action) { }); } -/** - * @param {Stream.TransformOptions['transform']} transform - * @param {Stream.TransformOptions['flush']} flush - */ -function transform(transform, flush) { +function createTransform( + transform: TransformOptions['transform'], + flush: TransformOptions['flush'] +): Transform { return new Transform({ objectMode: true, transform, diff --git a/build/gulpfile.hygiene.mjs b/build/gulpfile.hygiene.mjs index 8c4da9471b8..a435869d685 100644 --- a/build/gulpfile.hygiene.mjs +++ b/build/gulpfile.hygiene.mjs @@ -7,7 +7,7 @@ import es from 'event-stream'; import path from 'path'; import fs from 'fs'; import * as task from './lib/task.ts'; -import { hygiene } from './hygiene.mjs'; +import { hygiene } from './hygiene.ts'; const dirName = path.dirname(new URL(import.meta.url).pathname); diff --git a/build/gulpfile.reh.mjs b/build/gulpfile.reh.mjs index 24114225c04..aa5e6a9682e 100644 --- a/build/gulpfile.reh.mjs +++ b/build/gulpfile.reh.mjs @@ -30,7 +30,7 @@ import { cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileN import { vscodeWebResourceIncludes, createVSCodeWebFileContentMapper } from './gulpfile.vscode.web.mjs'; import * as cp from 'child_process'; import log from 'fancy-log'; -import buildfile from './buildfile.js'; +import buildfile from './buildfile.ts'; import { fileURLToPath } from 'url'; import * as fetchModule from './lib/fetch.ts'; import jsonEditor from 'gulp-json-editor'; diff --git a/build/gulpfile.vscode.mjs b/build/gulpfile.vscode.mjs index 1536bb114a6..d1d4fc5dc83 100644 --- a/build/gulpfile.vscode.mjs +++ b/build/gulpfile.vscode.mjs @@ -17,7 +17,7 @@ import * as util from './lib/util.ts'; import * as getVersionModule from './lib/getVersion.ts'; import * as dateModule from './lib/date.ts'; import * as task from './lib/task.ts'; -import buildfile from './buildfile.js'; +import buildfile from './buildfile.ts'; import * as optimize from './lib/optimize.ts'; import * as inlineMetaModule from './lib/inlineMeta.ts'; import packageJson from '../package.json' with { type: 'json' }; diff --git a/build/gulpfile.vscode.web.mjs b/build/gulpfile.vscode.web.mjs index 76a92c72aa8..2dac0dd9a47 100644 --- a/build/gulpfile.vscode.web.mjs +++ b/build/gulpfile.vscode.web.mjs @@ -21,7 +21,7 @@ import { compileBuildWithManglingTask } from './gulpfile.compile.mjs'; import * as extensions from './lib/extensions.ts'; import VinylFile from 'vinyl'; import jsonEditor from 'gulp-json-editor'; -import buildfile from './buildfile.js'; +import buildfile from './buildfile.ts'; import { fileURLToPath } from 'url'; const { getVersion } = getVersionModule; diff --git a/build/hygiene.mjs b/build/hygiene.ts similarity index 74% rename from build/hygiene.mjs rename to build/hygiene.ts index f3e37913405..72864a2edc0 100644 --- a/build/hygiene.mjs +++ b/build/hygiene.ts @@ -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 + import cp from 'child_process'; import es from 'event-stream'; import fs from 'fs'; @@ -11,10 +11,10 @@ import pall from 'p-all'; import path from 'path'; import VinylFile from 'vinyl'; import vfs from 'vinyl-fs'; -import { all, copyrightFilter, eslintFilter, indentationFilter, stylelintFilter, tsFormattingFilter, unicodeFilter } from './filters.js'; -import eslint from './gulp-eslint.js'; +import { all, copyrightFilter, eslintFilter, indentationFilter, stylelintFilter, tsFormattingFilter, unicodeFilter } from './filters.ts'; +import eslint from './gulp-eslint.ts'; import * as formatter from './lib/formatter.ts'; -import gulpstylelint from './stylelint.mjs'; +import gulpstylelint from './stylelint.ts'; const copyrightHeaderLines = [ '/*---------------------------------------------------------------------------------------------', @@ -23,16 +23,19 @@ const copyrightHeaderLines = [ ' *--------------------------------------------------------------------------------------------*/', ]; +interface VinylFileWithLines extends VinylFile { + __lines: string[]; +} + /** - * @param {string[] | NodeJS.ReadWriteStream} some - * @param {boolean} runEslint + * Main hygiene function that runs checks on files */ -export function hygiene(some, runEslint = true) { +export function hygiene(some: NodeJS.ReadWriteStream | string[], runEslint = true): NodeJS.ReadWriteStream { console.log('Starting hygiene...'); let errorCount = 0; - const productJson = es.through(function (file) { - const product = JSON.parse(file.contents.toString('utf8')); + const productJson = es.through(function (file: VinylFile) { + const product = JSON.parse(file.contents!.toString('utf8')); if (product.extensionsGallery) { console.error(`product.json: Contains 'extensionsGallery'`); @@ -42,9 +45,8 @@ export function hygiene(some, runEslint = true) { this.emit('data', file); }); - const unicode = es.through(function (file) { - /** @type {string[]} */ - const lines = file.contents.toString('utf8').split(/\r\n|\r|\n/); + const unicode = es.through(function (file: VinylFileWithLines) { + 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)); let skipNext = false; @@ -62,7 +64,7 @@ export function hygiene(some, runEslint = true) { if (line.match(/\s+(\*)/)) { // Naive multi-line comment check line = ''; } else { - const index = line.indexOf('\/\/'); + const index = line.indexOf('//'); line = index === -1 ? line : line.substring(0, index); } } @@ -80,9 +82,8 @@ export function hygiene(some, runEslint = true) { this.emit('data', file); }); - const indentation = es.through(function (file) { - /** @type {string[]} */ - const lines = file.__lines || file.contents.toString('utf8').split(/\r\n|\r|\n/); + const indentation = es.through(function (file: VinylFileWithLines) { + const lines = file.__lines || file.contents!.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; lines.forEach((line, i) => { @@ -103,7 +104,7 @@ export function hygiene(some, runEslint = true) { this.emit('data', file); }); - const copyrights = es.through(function (file) { + const copyrights = es.through(function (file: VinylFileWithLines) { const lines = file.__lines; for (let i = 0; i < copyrightHeaderLines.length; i++) { @@ -117,9 +118,9 @@ export function hygiene(some, runEslint = true) { this.emit('data', file); }); - const formatting = es.map(function (/** @type {any} */ file, cb) { + const formatting = es.map(function (file: any, cb) { try { - const rawInput = file.contents.toString('utf8'); + const rawInput = file.contents!.toString('utf8'); const rawOutput = formatter.format(file.path, rawInput); const original = rawInput.replace(/\r\n/gm, '\n'); @@ -137,13 +138,13 @@ export function hygiene(some, runEslint = true) { } }); - let input; + let input: NodeJS.ReadWriteStream; if (Array.isArray(some) || typeof some === 'string' || !some) { const options = { base: '.', follow: true, allowEmpty: true }; if (some) { - input = vfs.src(some, options).pipe(filter(all)); // split this up to not unnecessarily filter all a second time + input = vfs.src(some, options).pipe(filter(Array.from(all))); // split this up to not unnecessarily filter all a second time } else { - input = vfs.src(all, options); + input = vfs.src(Array.from(all), options); } } else { input = some; @@ -152,7 +153,7 @@ export function hygiene(some, runEslint = true) { const productJsonFilter = filter('product.json', { restore: true }); const snapshotFilter = filter(['**', '!**/*.snap', '!**/*.snap.actual']); const yarnLockFilter = filter(['**', '!**/yarn.lock']); - const unicodeFilterStream = filter(unicodeFilter, { restore: true }); + const unicodeFilterStream = filter(Array.from(unicodeFilter), { restore: true }); const result = input .pipe(filter((f) => Boolean(f.stat && !f.stat.isDirectory()))) @@ -164,20 +165,19 @@ export function hygiene(some, runEslint = true) { .pipe(unicodeFilterStream) .pipe(unicode) .pipe(unicodeFilterStream.restore) - .pipe(filter(indentationFilter)) + .pipe(filter(Array.from(indentationFilter))) .pipe(indentation) - .pipe(filter(copyrightFilter)) + .pipe(filter(Array.from(copyrightFilter))) .pipe(copyrights); - /** @type {import('stream').Stream[]} */ - const streams = [ - result.pipe(filter(tsFormattingFilter)).pipe(formatting) + const streams: NodeJS.ReadWriteStream[] = [ + result.pipe(filter(Array.from(tsFormattingFilter))).pipe(formatting) ]; if (runEslint) { streams.push( result - .pipe(filter(eslintFilter)) + .pipe(filter(Array.from(eslintFilter))) .pipe( eslint((results) => { errorCount += results.warningCount; @@ -188,7 +188,7 @@ export function hygiene(some, runEslint = true) { } streams.push( - result.pipe(filter(stylelintFilter)).pipe(gulpstylelint(((message, isError) => { + result.pipe(filter(Array.from(stylelintFilter))).pipe(gulpstylelint(((message: string, isError: boolean) => { if (isError) { console.error(message); errorCount++; @@ -201,7 +201,7 @@ export function hygiene(some, runEslint = true) { let count = 0; return es.merge(...streams).pipe( es.through( - function (data) { + function (data: unknown) { count++; if (process.env['TRAVIS'] && count % 10 === 0) { process.stdout.write('.'); @@ -225,14 +225,11 @@ export function hygiene(some, runEslint = true) { ); } -/** - * @param {string[]} paths - */ -function createGitIndexVinyls(paths) { +function createGitIndexVinyls(paths: string[]): Promise { const repositoryPath = process.cwd(); const fns = paths.map((relativePath) => () => - new Promise((c, e) => { + new Promise((c, e) => { const fullPath = path.join(repositoryPath, relativePath); fs.stat(fullPath, (err, stat) => { @@ -251,32 +248,30 @@ function createGitIndexVinyls(paths) { return e(err); } - c( - new VinylFile({ - path: fullPath, - base: repositoryPath, - contents: out, - stat, - }) - ); + c(new VinylFile({ + path: fullPath, + base: repositoryPath, + contents: out, + stat: stat, + })); } ); }); }) ); - return pall(fns, { concurrency: 4 }).then((r) => r.filter((p) => !!p)); + return pall(fns, { concurrency: 4 }).then((r) => r.filter((p): p is VinylFile => !!p)); } // this allows us to run hygiene as a git pre-commit hook if (import.meta.main) { - process.on('unhandledRejection', (reason, p) => { + process.on('unhandledRejection', (reason: unknown, p: Promise) => { console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); process.exit(1); }); if (process.argv.length > 2) { - hygiene(process.argv.slice(2)).on('error', (err) => { + hygiene(process.argv.slice(2)).on('error', (err: Error) => { console.error(); console.error(err); process.exit(1); @@ -300,15 +295,14 @@ if (import.meta.main) { createGitIndexVinyls(some) .then( (vinyls) => { - /** @type {Promise} */ - return (new Promise((c, e) => - hygiene(es.readArray(vinyls).pipe(filter(all))) + return new Promise((c, e) => + hygiene(es.readArray(vinyls).pipe(filter(Array.from(all)))) .on('end', () => c()) .on('error', e) - )); + ); } ) - .catch((err) => { + .catch((err: Error) => { console.error(); console.error(err); process.exit(1); diff --git a/build/lib/mangle/index.ts b/build/lib/mangle/index.ts index e20f37f4cbb..e53c58d32eb 100644 --- a/build/lib/mangle/index.ts +++ b/build/lib/mangle/index.ts @@ -11,7 +11,7 @@ import ts from 'typescript'; import { pathToFileURL } from 'url'; import workerpool from 'workerpool'; import { StaticLanguageServiceHost } from './staticLanguageServiceHost.ts'; -import * as buildfile from '../../buildfile.js'; +import * as buildfile from '../../buildfile.ts'; class ShortIdent { diff --git a/build/lib/node.js b/build/lib/node.ts similarity index 85% rename from build/lib/node.js rename to build/lib/node.ts index 0b07708c698..1825546deb9 100644 --- a/build/lib/node.js +++ b/build/lib/node.ts @@ -9,7 +9,11 @@ import fs from 'fs'; const root = path.dirname(path.dirname(import.meta.dirname)); const npmrcPath = path.join(root, 'remote', '.npmrc'); const npmrc = fs.readFileSync(npmrcPath, 'utf8'); -const version = /^target="(.*)"$/m.exec(npmrc)[1]; +const version = /^target="(.*)"$/m.exec(npmrc)?.[1]; + +if (!version) { + throw new Error('Failed to extract Node version from .npmrc'); +} const platform = process.platform; const arch = process.arch; diff --git a/build/setup-npm-registry.js b/build/setup-npm-registry.ts similarity index 75% rename from build/setup-npm-registry.js rename to build/setup-npm-registry.ts index cd6ba54e73f..670c3e339db 100644 --- a/build/setup-npm-registry.js +++ b/build/setup-npm-registry.ts @@ -2,16 +2,14 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// @ts-check + import { promises as fs } from 'fs'; import path from 'path'; /** - * @param {string} dir - * - * @returns {AsyncGenerator} + * Recursively find all package-lock.json files in a directory */ -async function* getPackageLockFiles(dir) { +async function* getPackageLockFiles(dir: string): AsyncGenerator { const files = await fs.readdir(dir); for (const file of files) { @@ -27,20 +25,18 @@ async function* getPackageLockFiles(dir) { } /** - * @param {string} url - * @param {string} file + * Replace the registry URL in a package-lock.json file */ -async function setup(url, file) { +async function setup(url: string, file: string): Promise { let contents = await fs.readFile(file, 'utf8'); contents = contents.replace(/https:\/\/registry\.[^.]+\.org\//g, url); await fs.writeFile(file, contents); } /** - * @param {string} url - * @param {string} dir + * Main function to set up custom NPM registry */ -async function main(url, dir) { +async function main(url: string, dir?: string): Promise { const root = dir ?? process.cwd(); for await (const file of getPackageLockFiles(root)) { diff --git a/build/stylelint.mjs b/build/stylelint.ts similarity index 78% rename from build/stylelint.mjs rename to build/stylelint.ts index f4080ca13e0..037fe110615 100644 --- a/build/stylelint.mjs +++ b/build/stylelint.ts @@ -2,27 +2,31 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// @ts-check import es from 'event-stream'; import vfs from 'vinyl-fs'; -import { stylelintFilter } from './filters.js'; +import { stylelintFilter } from './filters.ts'; import { getVariableNameValidator } from './lib/stylelint/validateVariableNames.ts'; +interface FileWithLines { + __lines?: string[]; + relative: string; + contents: Buffer; +} + +type Reporter = (message: string, isError: boolean) => void; + /** - * use regex on lines - * - * @param {(arg0: string, arg1: boolean) => void} reporter + * Stylelint gulpfile task */ -export default function gulpstylelint(reporter) { +export default function gulpstylelint(reporter: Reporter): NodeJS.ReadWriteStream { const variableValidator = getVariableNameValidator(); let errorCount = 0; const monacoWorkbenchPattern = /\.monaco-workbench/; const restrictedPathPattern = /^src[\/\\]vs[\/\\](base|platform|editor)[\/\\]/; const layerCheckerDisablePattern = /\/\*\s*stylelint-disable\s+layer-checker\s*\*\//; - return es.through(function (file) { - /** @type {string[]} */ + return es.through(function (this, file: FileWithLines) { const lines = file.__lines || file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; @@ -32,7 +36,7 @@ export default function gulpstylelint(reporter) { const isLayerCheckerDisabled = lines.some(line => layerCheckerDisablePattern.test(line)); lines.forEach((line, i) => { - variableValidator(line, unknownVariable => { + variableValidator(line, (unknownVariable: string) => { reporter(file.relative + '(' + (i + 1) + ',1): Unknown variable: ' + unknownVariable, true); errorCount++; }); @@ -49,13 +53,12 @@ export default function gulpstylelint(reporter) { reporter('All valid variable names are in `build/lib/stylelint/vscode-known-variables.json`\nTo update that file, run `./scripts/test-documentation.sh|bat.`', false); } this.emit('end'); - } - ); + }); } -function stylelint() { +function stylelint(): NodeJS.ReadWriteStream { return vfs - .src(stylelintFilter, { base: '.', follow: true, allowEmpty: true }) + .src(Array.from(stylelintFilter), { base: '.', follow: true, allowEmpty: true }) .pipe(gulpstylelint((message, isError) => { if (isError) { console.error(message); @@ -67,7 +70,7 @@ function stylelint() { } if (import.meta.main) { - stylelint().on('error', (err) => { + stylelint().on('error', (err: Error) => { console.error(); console.error(err); process.exit(1); diff --git a/package.json b/package.json index 5f3c09c187e..d24b283d591 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "watch-extensions": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js watch-extensions watch-extension-media", "watch-extensionsd": "deemon npm run watch-extensions", "kill-watch-extensionsd": "deemon --kill npm run watch-extensions", - "precommit": "node build/hygiene.mjs", + "precommit": "node build/hygiene.ts", "gulp": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js", "electron": "node build/lib/electron.ts", "7z": "7z", @@ -55,8 +55,8 @@ "compile-web": "node ./node_modules/gulp/bin/gulp.js compile-web", "watch-web": "node ./node_modules/gulp/bin/gulp.js watch-web", "watch-cli": "node ./node_modules/gulp/bin/gulp.js watch-cli", - "eslint": "node build/eslint.mjs", - "stylelint": "node build/stylelint.mjs", + "eslint": "node build/eslint.ts", + "stylelint": "node build/stylelint.ts", "playwright-install": "npm exec playwright install", "compile-build": "node ./node_modules/gulp/bin/gulp.js compile-build-with-mangling", "compile-extensions-build": "node ./node_modules/gulp/bin/gulp.js compile-extensions-build", diff --git a/scripts/code-server.sh b/scripts/code-server.sh index 59d53726240..f1604b75536 100755 --- a/scripts/code-server.sh +++ b/scripts/code-server.sh @@ -15,7 +15,7 @@ function code() { node build/lib/preLaunch.ts fi - NODE=$(node build/lib/node.js) + NODE=$(node build/lib/node.ts) if [ ! -e $NODE ];then # Load remote node npm run gulp node diff --git a/scripts/code-web.bat b/scripts/code-web.bat index 5454a9b1ad4..6ed8fd984fd 100644 --- a/scripts/code-web.bat +++ b/scripts/code-web.bat @@ -9,7 +9,7 @@ pushd %~dp0\.. call npm run download-builtin-extensions :: Node executable -FOR /F "tokens=*" %%g IN ('node build/lib/node.js') do (SET NODE=%%g) +FOR /F "tokens=*" %%g IN ('node build/lib/node.ts') do (SET NODE=%%g) if not exist "%NODE%" ( :: Download nodejs executable for remote diff --git a/scripts/code-web.sh b/scripts/code-web.sh index c5d5fcfae4f..a0de889f1fb 100755 --- a/scripts/code-web.sh +++ b/scripts/code-web.sh @@ -13,13 +13,13 @@ function code() { # Sync built-in extensions npm run download-builtin-extensions - NODE=$(node build/lib/node.js) + NODE=$(node build/lib/node.ts) if [ ! -e $NODE ];then # Load remote node npm run gulp node fi - NODE=$(node build/lib/node.js) + NODE=$(node build/lib/node.ts) $NODE ./scripts/code-web.js "$@" }