diff --git a/.gitignore b/.gitignore index 40f967eea81da..1161f7db40b88 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ errorShots examples/*/src-gen examples/*/gen-webpack.config.js examples/*/gen-webpack.node.config.js +examples/*/gen-esbuild.*.mjs examples/*/.test .browser_modules **/docs/api diff --git a/dev-packages/application-manager/package.json b/dev-packages/application-manager/package.json index e9edeeb55400b..167bfaf4e36e9 100644 --- a/dev-packages/application-manager/package.json +++ b/dev-packages/application-manager/package.json @@ -36,6 +36,7 @@ "@theia/application-package": "1.57.0", "@theia/ffmpeg": "1.57.0", "@theia/native-webpack-plugin": "1.57.0", + "@theia/native-esbuild-plugin": "1.57.0", "@types/fs-extra": "^4.0.2", "@types/semver": "^7.5.0", "babel-loader": "^8.2.2", @@ -44,6 +45,9 @@ "copy-webpack-plugin": "^8.1.1", "css-loader": "^6.2.0", "electron-rebuild": "^3.2.7", + "esbuild": "^0.24.0", + "esbuild-plugins-node-modules-polyfill": "^1.6.7", + "esbuild-plugin-copy": "^2.1.1", "fs-extra": "^4.0.2", "http-server": "^14.1.1", "ignore-loader": "^0.1.2", diff --git a/dev-packages/application-manager/src/application-package-manager.ts b/dev-packages/application-manager/src/application-package-manager.ts index 09d3d26956789..e44bb3fbfc905 100644 --- a/dev-packages/application-manager/src/application-package-manager.ts +++ b/dev-packages/application-manager/src/application-package-manager.ts @@ -19,7 +19,7 @@ import * as fs from 'fs-extra'; import * as cp from 'child_process'; import * as semver from 'semver'; import { ApplicationPackage, ApplicationPackageOptions } from '@theia/application-package'; -import { WebpackGenerator, FrontendGenerator, BackendGenerator } from './generator'; +import { BundlerGenerator, FrontendGenerator, BackendGenerator } from './generator'; import { ApplicationProcess } from './application-process'; import { GeneratorOptions } from './generator/abstract-generator'; import yargs = require('yargs'); @@ -73,12 +73,14 @@ export class ApplicationPackageManager { } async clean(): Promise { - const webpackGenerator = new WebpackGenerator(this.pck); + const bundlerGenerator = new BundlerGenerator(this.pck); await Promise.all([ this.remove(this.pck.lib()), this.remove(this.pck.srcGen()), - this.remove(webpackGenerator.genConfigPath), - this.remove(webpackGenerator.genNodeConfigPath) + this.remove(bundlerGenerator.genConfigPath), + this.remove(bundlerGenerator.genNodeConfigPath), + this.remove(bundlerGenerator.genESBuildBrowserPath), + this.remove(bundlerGenerator.genESBuildNodePath), ]); } @@ -99,7 +101,7 @@ export class ApplicationPackageManager { throw error; } await Promise.all([ - new WebpackGenerator(this.pck, options).generate(), + new BundlerGenerator(this.pck, options).generate(), new BackendGenerator(this.pck, options).generate(), new FrontendGenerator(this.pck, options).generate(), ]); @@ -111,9 +113,15 @@ export class ApplicationPackageManager { } async build(args: string[] = [], options: GeneratorOptions = {}): Promise { + const bundlerGenerator = new BundlerGenerator(this.pck); await this.generate(options); await this.copy(); - return this.__process.run('webpack', args); + if (await bundlerGenerator.preferESBuild()) { + const process = this.__process.spawn('node', [bundlerGenerator.esbuildPath, ...args]); + return this.__process.promisify('esbuild', process); + } else { + return this.__process.run('webpack', args); + } } start(args: string[] = []): cp.ChildProcess { diff --git a/dev-packages/application-manager/src/application-process.ts b/dev-packages/application-manager/src/application-process.ts index 7e735c24b27b1..d6fc80f1d0e01 100644 --- a/dev-packages/application-manager/src/application-process.ts +++ b/dev-packages/application-manager/src/application-process.ts @@ -78,7 +78,7 @@ export class ApplicationProcess { return this.resolveBin(parentDir, command); } - protected promisify(command: string, p: cp.ChildProcess): Promise { + promisify(command: string, p: cp.ChildProcess): Promise { return new Promise((resolve, reject) => { p.stdout!.on('data', data => this.pck.log(data.toString())); p.stderr!.on('data', data => this.pck.error(data.toString())); diff --git a/dev-packages/application-manager/src/generator/webpack-generator.ts b/dev-packages/application-manager/src/generator/bundler-generator.ts similarity index 60% rename from dev-packages/application-manager/src/generator/webpack-generator.ts rename to dev-packages/application-manager/src/generator/bundler-generator.ts index 3f32adda88f71..248a5d3b47c24 100644 --- a/dev-packages/application-manager/src/generator/webpack-generator.ts +++ b/dev-packages/application-manager/src/generator/bundler-generator.ts @@ -18,16 +18,42 @@ import * as paths from 'path'; import * as fs from 'fs-extra'; import { AbstractGenerator } from './abstract-generator'; -export class WebpackGenerator extends AbstractGenerator { +export class BundlerGenerator extends AbstractGenerator { async generate(): Promise { - await this.write(this.genConfigPath, this.compileWebpackConfig()); - if (!this.pck.isBrowserOnly()) { - await this.write(this.genNodeConfigPath, this.compileNodeWebpackConfig()); + if (await this.preferESBuild()) { + await this.write(this.genESBuildBrowserPath, this.compileESBuildBrowserConfig()); + if (!this.pck.isBrowserOnly()) { + await this.write(this.genESBuildNodePath, this.compileESBuildNodeConfig()); + if (this.pck.isElectron()) { + await this.write(this.genESBuildElectronPath, this.compileESBuildElectronConfig()); + } + } + if (await this.shouldGenerateUserESBuildConfig()) { + await this.write(this.esbuildPath, this.compileESBuildUserConfig()); + } + } else { + await this.write(this.genConfigPath, this.compileWebpackConfig()); + if (!this.pck.isBrowserOnly()) { + await this.write(this.genNodeConfigPath, this.compileNodeWebpackConfig()); + } + if (await this.shouldGenerateUserWebpackConfig()) { + await this.write(this.configPath, this.compileUserWebpackConfig()); + } } - if (await this.shouldGenerateUserWebpackConfig()) { - await this.write(this.configPath, this.compileUserWebpackConfig()); + } + + async preferESBuild(): Promise { + // If a esbuild file already exists, prefer esbuild + if (await fs.pathExists(this.esbuildPath)) { + return true; + } + // If a webpack file already exists, prefer webpack + if (await fs.pathExists(this.configPath)) { + return false; } + // Otherwise, prefer ESBuild (for performance) + return true; } protected async shouldGenerateUserWebpackConfig(): Promise { @@ -35,7 +61,15 @@ export class WebpackGenerator extends AbstractGenerator { return true; } const content = await fs.readFile(this.configPath, 'utf8'); - return content.indexOf('gen-webpack') === -1; + return !content.includes('gen-webpack'); + } + + protected async shouldGenerateUserESBuildConfig(): Promise { + if (!(await fs.pathExists(this.esbuildPath))) { + return true; + } + const content = await fs.readFile(this.esbuildPath, 'utf8'); + return !content.includes('gen-esbuild'); } get configPath(): string { @@ -50,6 +84,22 @@ export class WebpackGenerator extends AbstractGenerator { return this.pck.path('gen-webpack.node.config.js'); } + get esbuildPath(): string { + return this.pck.path('esbuild.mjs'); + } + + get genESBuildBrowserPath(): string { + return this.pck.path('gen-esbuild.browser.mjs'); + } + + get genESBuildNodePath(): string { + return this.pck.path('gen-esbuild.node.mjs'); + } + + get genESBuildElectronPath(): string { + return this.pck.path('gen-esbuild.electron.mjs'); + } + protected compileWebpackConfig(): string { return `/** * Don't touch this file. It will be regenerated by theia build. @@ -496,6 +546,255 @@ module.exports = { nativePlugin, ignoredResources }; +`; + } + + compileESBuildBrowserConfig(): string { + return `/** + * Don't touch this file. It will be regenerated by theia build. + * To customize the build process, change ./esbuild.mjs + */ +import { nodeModulesPolyfillPlugin } from 'esbuild-plugins-node-modules-polyfill'; +import { copy } from 'esbuild-plugin-copy'; +import { problemMatcherPlugin } from '@theia/native-esbuild-plugin'; +import yargs from 'yargs'; +import resolvePackagePath from 'resolve-package-path'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +function join(...parts) { + return path.join(...parts).replace(/\\\\/g, '/'); +} + +const { mode, staticCompression, watch } = yargs.option('mode', { + description: "Mode to use", + choices: ["development", "production"], + default: "production" +}).option('static-compression', { + description: 'Controls whether to enable compression of static artifacts. TODO: Not implemented yet.', + type: 'boolean', + default: true +}).option('watch', { + description: 'Controls whether to enable watch mode', + type: 'boolean', + default: false +}).argv; + +const production = mode === 'production'; +const sourcemap = production ? false : 'linked'; +const minify = production; + +export { mode, staticCompression, watch, sourcemap, minify }; + +/** + * @type {Record} + */ +export const loader = { + '.css': 'css', + '.ttf': 'dataurl', + '.eot': 'dataurl', + '.svg': 'dataurl', + '.woff': 'dataurl', + '.woff2': 'dataurl', + '.jpg': 'dataurl', + '.png': 'dataurl', + '.gif': 'dataurl', + '.wasm': 'dataurl', + '.plist': 'dataurl', + '.node': 'file' +}; + +/** + * {@type {import('esbuild').BuildOptions}} + */ +export const browserOptions = { + entryPoints: { + 'bundle': './src-gen/frontend/index.js', + 'secondary-window': './src-gen/frontend/secondary-index.js', + ${this.ifMonaco(() => "'editor.worker': '@theia/monaco-editor-core/esm/vs/editor/editor.worker.js'")} + }, + assetNames: '[name]', + bundle: true, + outdir: 'lib/frontend', + platform: 'browser', + // Support UMD libraries + // but ensure that we also prioritize browser exports where possible + mainFields: ['browser', 'module', 'main'], + loader, + minify, + sourcemap, + plugins: [ + problemMatcherPlugin(watch, 'browser'), + nodeModulesPolyfillPlugin({ + globals: { + Buffer: true, + process: false + } + }), + copy({ + assets: [ + { + // copy secondary window html file to lib folder + from: join(__dirname, 'src-gen/frontend/secondary-window.html'), + to: join(__dirname, 'lib', 'frontend') + }${this.ifPackage('@theia/plugin-ext', `, + { + // copy webview files to lib folder + from: join(resolvePackagePath('@theia/plugin-ext', __dirname), '..', 'src', 'main', 'browser', 'webview', 'pre', '*'), + to: join(__dirname, 'lib', 'webview', 'pre') + }`)}${this.ifPackage('@theia/plugin-ext-vscode', `, + { + // copy frontend plugin host files + from: join(resolvePackagePath('@theia/plugin-ext-vscode', __dirname), '..', 'lib', 'node', 'context', 'plugin-vscode-init-fe.js'), + to: join(__dirname, 'lib', 'frontend', 'context') + }`)} + ] + }) + ] +}; +`; + } + + compileESBuildNodeConfig(): string { + return `/** + * Don't touch this file. It will be regenerated by theia build. + * To customize the build process, change ./esbuild.mjs + */ +import { nativeDependenciesPlugin, problemMatcherPlugin } from '@theia/native-esbuild-plugin'; +import { watch, loader, minify, sourcemap } from './gen-esbuild.browser.mjs'; + +/** + * @type {Record} + */ +export const nativeBindings = { + drivelist: 'drivelist/build/Release/drivelist.node' +}; + +/** + * {@type {import('esbuild').BuildOptions}} + */ +export const nodeOptions = { + entryPoints: { + 'main': './src-gen/backend/main', + 'ipc-bootstrap': '@theia/core/lib/node/messaging/ipc-bootstrap', + ${this.ifElectron("'electron-main': './src-gen/backend/electron-main',")} + ${this.ifPackage('@theia/plugin-ext', () => `// VS Code extension support: + 'plugin-host': '@theia/plugin-ext/lib/hosted/node/plugin-host',`)} + ${this.ifPackage('@theia/plugin-ext-headless', () => `// Theia Headless Plugin support: + 'plugin-host-headless': '@theia/plugin-ext-headless/lib/hosted/node/plugin-host-headless',`)} + ${this.ifPackage('@theia/process', () => `// Make sure the node-pty thread worker can be executed: + 'worker/conoutSocketWorker': 'node-pty/lib/worker/conoutSocketWorker',`)} + ${this.ifPackage('@theia/dev-container', () => `// VS Code Dev-Container communication: + 'dev-container-server': '@theia/dev-container/lib/dev-container-server/dev-container-server',`)} + ${this.ifPackage('@theia/plugin-ext', "'backend-init-theia': '@theia/plugin-ext/lib/hosted/node/scanners/backend-init-theia',")} + ${this.ifPackage('@theia/filesystem', "'parcel-watcher': '@theia/filesystem/lib/node/parcel-watcher',")} + ${this.ifPackage('@theia/plugin-ext-vscode', "'plugin-vscode-init': '@theia/plugin-ext-vscode/lib/node/plugin-vscode-init',")} + ${this.ifPackage('@theia/api-provider-sample', "'gotd-api-init': '@theia/api-provider-sample/lib/plugin/gotd-api-init',")} + ${this.ifPackage('@theia/git', "'git-locator-host': '@theia/git/lib/node/git-locator/git-locator-host',")} + }, + assetNames: 'native/[name]', + bundle: true, + outdir: 'lib/backend', + platform: 'node', + mainFields: ['node', 'module', 'main'], + external: ['electron'], + loader, + minify, + sourcemap, + plugins: [ + problemMatcherPlugin(watch, 'node'), + nativeDependenciesPlugin({ + pty: ${this.ifPackage('@theia/process', 'true', 'false')}, + ripgrep: ${this.ifPackage(['@theia/search-in-workspace', '@theia/file-search'], 'true', 'false')}, + trash: ${this.ifPackage('@theia/filesystem', 'true', 'false')}, + nativeBindings + }) + ] +}; +`; + }; + + compileESBuildUserConfig(): string { + return `/** + * This file can be edited to the ESBuild build process. + * To reset, delete this file and rerun theia build again. + */ +import { browserOptions, watch } from './gen-esbuild.browser.mjs'; +${this.ifBrowserOnly(`import esbuild from 'esbuild'; + +const browserContext = await esbuild.context(browserOptions); + +if (watch) { + await browserContext.watch(); +} else { + try { + await browserContext.rebuild(); + await browserContext.dispose(); + } catch (err) { + process.exit(1); + } +}`, `import { nodeOptions } from './gen-esbuild.node.mjs'; +${this.ifElectron("import { electronOptions } from './gen-esbuild.electron.mjs';")} +import esbuild from 'esbuild'; + +const browserContext = await esbuild.context(browserOptions); +const nodeContext = await esbuild.context(nodeOptions); +${this.ifElectron('const electronContext = await esbuild.context(electronOptions);')} + +if (watch) { + await Promise.all([ + browserContext.watch(), + nodeContext.watch(), + ${this.ifElectron('electronContext.watch(),')} + ]); +} else { + try { + await Promise.all([ + browserContext.rebuild(), + nodeContext.rebuild(), + ${this.ifElectron('electronContext.rebuild(),')} + ]); + await Promise.all([ + browserContext.dispose(), + nodeContext.dispose(), + ${this.ifElectron('electronContext.dispose(),')} + ]); + } catch (err) { + process.exit(1); + } +}`)} +`; + } + + compileESBuildElectronConfig(): string { + return `/** + * Don't touch this file. It will be regenerated by theia build. + * To customize the build process, change ./esbuild.mjs + */ +import { problemMatcherPlugin } from '@theia/native-esbuild-plugin'; +import { watch, loader, minify, sourcemap } from './gen-esbuild.browser.mjs'; + +/** + * {@type {import('esbuild').BuildOptions}} + */ +export const electronOptions = { + entryPoints: { + 'preload': './src-gen/frontend/preload' + }, + bundle: true, + outdir: 'lib/frontend', + platform: 'node', + mainFields: ['node', 'module', 'main'], + external: ['electron'], + loader, + minify, + sourcemap, + plugins: [ + problemMatcherPlugin(watch, 'electron') + ] +}; `; } diff --git a/dev-packages/application-manager/src/generator/frontend-generator.ts b/dev-packages/application-manager/src/generator/frontend-generator.ts index bbfd134bdb3b8..45a594e8d23ac 100644 --- a/dev-packages/application-manager/src/generator/frontend-generator.ts +++ b/dev-packages/application-manager/src/generator/frontend-generator.ts @@ -66,6 +66,7 @@ export class FrontendGenerator extends AbstractGenerator { + ${this.pck.props.frontend.config.applicationName}`; } diff --git a/dev-packages/application-manager/src/generator/index.ts b/dev-packages/application-manager/src/generator/index.ts index 9d3cac8ce4b0a..a76dbbc788134 100644 --- a/dev-packages/application-manager/src/generator/index.ts +++ b/dev-packages/application-manager/src/generator/index.ts @@ -14,6 +14,6 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -export * from './webpack-generator'; +export * from './bundler-generator'; export * from './frontend-generator'; export * from './backend-generator'; diff --git a/dev-packages/application-manager/tsconfig.json b/dev-packages/application-manager/tsconfig.json index bff525f824f30..79dd071efe110 100644 --- a/dev-packages/application-manager/tsconfig.json +++ b/dev-packages/application-manager/tsconfig.json @@ -15,6 +15,9 @@ { "path": "../ffmpeg" }, + { + "path": "../native-esbuild-plugin" + }, { "path": "../native-webpack-plugin" } diff --git a/dev-packages/native-esbuild-plugin/.eslintrc.js b/dev-packages/native-esbuild-plugin/.eslintrc.js new file mode 100644 index 0000000000000..13089943582b6 --- /dev/null +++ b/dev-packages/native-esbuild-plugin/.eslintrc.js @@ -0,0 +1,10 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + extends: [ + '../../configs/build.eslintrc.json' + ], + parserOptions: { + tsconfigRootDir: __dirname, + project: 'tsconfig.json' + } +}; diff --git a/dev-packages/native-esbuild-plugin/README.md b/dev-packages/native-esbuild-plugin/README.md new file mode 100644 index 0000000000000..4226f155557d1 --- /dev/null +++ b/dev-packages/native-esbuild-plugin/README.md @@ -0,0 +1,29 @@ +
+ +
+ +theia-ext-logo + +

ECLIPSE THEIA - NATIVE-WEBPACK-PLUGIN

+ +
+ +
+ +## Description + +The `@theia/native-webpack-plugin` package contains a webpack plugin that is used to handle native dependencies for bundling Theia based application backends. + +## Additional Information + +- [Theia - GitHub](https://github.com/eclipse-theia/theia) +- [Theia - Website](https://theia-ide.org/) + +## License + +- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/) +- [δΈ€ (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp) + +## Trademark +"Theia" is a trademark of the Eclipse Foundation +https://www.eclipse.org/theia diff --git a/dev-packages/native-esbuild-plugin/package.json b/dev-packages/native-esbuild-plugin/package.json new file mode 100644 index 0000000000000..464ecb9384e84 --- /dev/null +++ b/dev-packages/native-esbuild-plugin/package.json @@ -0,0 +1,36 @@ +{ + "name": "@theia/native-esbuild-plugin", + "version": "1.57.0", + "description": "ESBuild Plugin for native dependencies of Theia.", + "publishConfig": { + "access": "public" + }, + "license": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0", + "repository": { + "type": "git", + "url": "https://github.com/eclipse-theia/theia.git" + }, + "bugs": { + "url": "https://github.com/eclipse-theia/theia/issues" + }, + "homepage": "https://github.com/eclipse-theia/theia", + "files": [ + "lib", + "src" + ], + "main": "lib/index.js", + "typings": "lib/index.d.ts", + "scripts": { + "build": "theiaext build", + "clean": "theiaext clean", + "compile": "theiaext compile", + "lint": "theiaext lint", + "test": "theiaext test", + "watch": "theiaext watch" + }, + "dependencies": { + "detect-libc": "^2.0.2", + "tslib": "^2.6.2", + "webpack": "^5.76.0" + } +} diff --git a/dev-packages/native-esbuild-plugin/src/index.ts b/dev-packages/native-esbuild-plugin/src/index.ts new file mode 100644 index 0000000000000..586b890edf0f6 --- /dev/null +++ b/dev-packages/native-esbuild-plugin/src/index.ts @@ -0,0 +1,17 @@ +// ***************************************************************************** +// Copyright (C) 2023 TypeFox and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0. +// +// This Source Code may also be made available under the following Secondary +// Licenses when the conditions for such availability set forth in the Eclipse +// Public License v. 2.0 are satisfied: GNU General Public License, version 2 +// with the GNU Classpath Exception which is available at +// https://www.gnu.org/software/classpath/license.html. +// +// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 +// ***************************************************************************** + +export * from './native-esbuild-plugin'; diff --git a/dev-packages/native-esbuild-plugin/src/native-esbuild-plugin.ts b/dev-packages/native-esbuild-plugin/src/native-esbuild-plugin.ts new file mode 100644 index 0000000000000..703db7fc9ab7a --- /dev/null +++ b/dev-packages/native-esbuild-plugin/src/native-esbuild-plugin.ts @@ -0,0 +1,231 @@ +// ***************************************************************************** +// Copyright (C) 2024 TypeFox and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0. +// +// This Source Code may also be made available under the following Secondary +// Licenses when the conditions for such availability set forth in the Eclipse +// Public License v. 2.0 are satisfied: GNU General Public License, version 2 +// with the GNU Classpath Exception which is available at +// https://www.gnu.org/software/classpath/license.html. +// +// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 +// ***************************************************************************** + +import * as path from 'path'; +import * as fs from 'fs'; +import resolvePackagePath = require('resolve-package-path'); + +import type { Plugin, PluginBuild } from 'esbuild'; + +function join(...parts: string[]): string { + return path.join(...parts).replace(/\\/g, '/'); +} + +function resolveModulePath(module: string): string { + const modulePath = resolvePackagePath(module, process.cwd()); + if (!modulePath) { + throw new Error('Could not resolve path of module: ' + module); + } + return path.resolve(modulePath, '..'); +} + +export function problemMatcherPlugin(watch: boolean, type: string): Plugin { + const buildType = watch ? 'watch' : 'build'; + const prefix = `[${buildType}/${type}]`; + let time = Date.now(); + return { + name: 'esbuild-problem-matcher', + setup(build: PluginBuild): void { + build.onStart(() => { + time = Date.now(); + console.log(prefix + ' Build started'); + }); + build.onEnd(result => { + console.log(prefix + ' Finished with ' + result.errors.length + ' errors in ' + (Date.now() - time) + 'ms.'); + }); + }, + }; +}; + +export interface NativeDependenciesPluginOptions { + trash: boolean; + ripgrep: boolean; + pty: boolean; + nativeBindings: Record; +} + +export function nativeDependenciesPlugin(options: NativeDependenciesPluginOptions): Plugin { + const plugin = new PluginImpl(options); + // create wrapper over plugin + // esbuild validates the plugin object and expects no additional properties + return { + name: plugin.name, + setup: plugin.setup.bind(plugin) + }; +} + +class PluginImpl implements Plugin { + + name = '@theia/native-esbuild-plugin'; + + private bindings: Record = {}; + private options: NativeDependenciesPluginOptions; + + constructor(options: NativeDependenciesPluginOptions) { + this.options = options; + for (const [name, value] of Object.entries(options.nativeBindings)) { + this.nativeBinding(name, value); + } + } + + nativeBinding(dependency: string, nodePath: string): void { + this.bindings[dependency] = nodePath; + } + + setup(build: PluginBuild): void { + const outdir = build.initialOptions.outdir; + if (!outdir) { + throw new Error('The `outdir` option is required.'); + } + build.onResolve({ filter: /^@vscode\/windows-ca-certs$/ }, () => { + const windows = process.platform === 'win32'; + return { + path: windows + ? join(resolveModulePath('@vscode/windows-ca-certs'), 'build', 'Release', 'crypt32.node') + : '', + // Simply mark the dependency as external on non-Windows platforms + external: !windows + }; + }); + build.onResolve({ filter: /\.\/build\/Release\/keymapping$/ }, () => ({ + path: join(resolveModulePath('native-keymap'), 'build', 'Release', 'keymapping.node'), + namespace: 'node-file' + })); + build.onResolve({ filter: /\.\/build\/Release\/watcher\.node$/ }, () => { + let name = `@parcel/watcher-${process.platform}-${process.arch}`; + if (process.platform === 'linux') { + const { MUSL, family } = require('detect-libc'); + if (family === MUSL) { + name += '-musl'; + } else { + name += '-glibc'; + } + } + return { + path: join(resolveModulePath(name), 'watcher.node') + }; + }); + build.onLoad({ filter: /bindings[\\\/]bindings\.js$/ }, async () => ({ + contents: bindingsReplacement(this.bindings), + loader: 'js' + })); + build.onLoad({ filter: /@vscode[\\\/]ripgrep[\\\/]lib[\\\/]index\.js$/ }, async () => ({ + contents: 'exports.rgPath = require("path").join(__dirname, `./native/rg${process.platform === "win32" ? ".exe" : ""}`);', + loader: 'js' + })); + build.onEnd(() => { + if (this.options.trash) { + copyTrashHelper(outdir); + } + if (this.options.ripgrep) { + copyRipgrep(outdir); + } + if (this.options.pty) { + copyNodePtySpawnHelper(outdir); + } + }); + this.setupNodeRequires(build); + } + + private setupNodeRequires(build: PluginBuild): void { + // By default, ESBuild does not handle `.node` files. We need to handle them ourselves. + // When using the `file` loader directly, the files only get exposed via their paths. + // However, we want to load them directly as native modules via `require`. + build.onResolve({ filter: /\.node$/, namespace: 'file' }, args => { + try { + // Move the resolved path to the `node-file` namespace to load it as a native module. + const resolved = require.resolve(args.path, { paths: [args.resolveDir] }); + return { + path: resolved, + namespace: 'node-file', + }; + } catch { + // If the module cannot be resolved, mark it as external. + return { + external: true + }; + } + }); + build.onLoad({ filter: /.*/, namespace: 'node-file' }, args => ({ + // Replace the require statement with a direct require call to the native module. + contents: ` + import path from ${JSON.stringify(args.path)} + try { module.exports = require(path) } + catch { throw new Error('Could not load native module from "${path.basename(args.path)}"') } + `, + })); + build.onResolve({ filter: /\.node$/, namespace: 'node-file' }, args => ({ + // Finally, resolve the `.node` file to the local path. + path: args.path, + namespace: 'file', + })); + } +} + +async function copyRipgrep(outdir: string): Promise { + const fileName = process.platform === 'win32' ? 'rg.exe' : 'rg'; + const sourceFile = join(resolveModulePath('@vscode/ripgrep'), 'bin', fileName); + const targetFile = path.join(outdir, 'native', fileName); + await copyExecutable(sourceFile, targetFile); +} + +async function copyNodePtySpawnHelper(outdir: string): Promise { + const targetDirectory = path.resolve(outdir, '..', 'build', 'Release'); + if (process.platform === 'win32') { + const agentFile = join(resolveModulePath('node-pty'), 'build', 'Release', 'winpty-agent.exe'); + const targetAgentFile = path.join(targetDirectory, 'winpty-agent.exe'); + await copyExecutable(agentFile, targetAgentFile); + const dllFile = join(resolveModulePath('node-pty'), 'build', 'Release', 'winpty.dll'); + const targetDllFile = path.join(targetDirectory, 'winpty.dll'); + await copyExecutable(dllFile, targetDllFile); + } else if (process.platform === 'darwin') { + const sourceFile = join(resolveModulePath('node-pty'), 'build', 'Release', 'spawn-helper'); + const targetFile = path.join(targetDirectory, 'spawn-helper'); + await copyExecutable(sourceFile, targetFile); + } +} + +async function copyTrashHelper(outdir: string): Promise { + const fileName = process.platform === 'win32' ? 'windows-trash.exe' : 'macos-trash'; + if (process.platform === 'win32' || process.platform === 'darwin') { + const sourceFile = join(resolveModulePath('trash'), 'lib', fileName); + const targetFile = path.join(outdir, fileName); + await copyExecutable(sourceFile, targetFile); + } +} + +async function copyExecutable(source: string, target: string): Promise { + const targetDirectory = path.dirname(target); + await fs.promises.mkdir(targetDirectory, { recursive: true }); + await fs.promises.copyFile(source, target); + await fs.promises.chmod(target, 0o777); +} + +const bindingsReplacement = (bindings: Record) => { + const cases = []; + + for (const [module, node] of Object.entries(bindings)) { + cases.push(`${' '.repeat(8)}case '${module}': return require('${node}');`); + } + + return ` +module.exports = function (jsModule) { + switch (jsModule) { +${cases.join('/')} + } + throw new Error(\`unhandled module: "\${jsModule}"\`); +}`.trim(); +}; diff --git a/dev-packages/native-esbuild-plugin/src/package.spec.ts b/dev-packages/native-esbuild-plugin/src/package.spec.ts new file mode 100644 index 0000000000000..4e6f3abdcdccd --- /dev/null +++ b/dev-packages/native-esbuild-plugin/src/package.spec.ts @@ -0,0 +1,28 @@ +// ***************************************************************************** +// Copyright (C) 2023 TypeFox and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0. +// +// This Source Code may also be made available under the following Secondary +// Licenses when the conditions for such availability set forth in the Eclipse +// Public License v. 2.0 are satisfied: GNU General Public License, version 2 +// with the GNU Classpath Exception which is available at +// https://www.gnu.org/software/classpath/license.html. +// +// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 +// ***************************************************************************** + +/* note: this bogus test file is required so that + we are able to run mocha unit tests on this + package, without having any actual unit tests in it. + This way a coverage report will be generated, + showing 0% coverage, instead of no report. + This file can be removed once we have real unit + tests in place. */ + +describe('request package', () => { + + it('should support code coverage statistics', () => true); +}); diff --git a/dev-packages/native-esbuild-plugin/tsconfig.json b/dev-packages/native-esbuild-plugin/tsconfig.json new file mode 100644 index 0000000000000..b973ddbc673a2 --- /dev/null +++ b/dev-packages/native-esbuild-plugin/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../configs/base.tsconfig", + "compilerOptions": { + "composite": true, + "rootDir": "src", + "outDir": "lib" + }, + "include": [ + "src" + ], + "references": [] +} diff --git a/examples/browser-only/esbuild.mjs b/examples/browser-only/esbuild.mjs new file mode 100644 index 0000000000000..559314126d0c8 --- /dev/null +++ b/examples/browser-only/esbuild.mjs @@ -0,0 +1,19 @@ +/** + * This file can be edited to the ESBuild build process. + * To reset, delete this file and rerun theia build again. + */ +import { browserOptions, watch } from './gen-esbuild.browser.mjs'; +import esbuild from 'esbuild'; + +const browserContext = await esbuild.context(browserOptions); + +if (watch) { + await browserContext.watch(); +} else { + try { + await browserContext.rebuild(); + await browserContext.dispose(); + } catch (err) { + process.exit(1); + } +} diff --git a/examples/browser-only/webpack.config.js b/examples/browser-only/webpack.config.js deleted file mode 100644 index 40e4ee963ba9f..0000000000000 --- a/examples/browser-only/webpack.config.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * This file can be edited to customize webpack configuration. - * To reset delete this file and rerun theia build again. - */ -// @ts-check -const configs = require('./gen-webpack.config.js'); - - -/** - * Expose bundled modules on window.theia.moduleName namespace, e.g. - * window['theia']['@theia/core/lib/common/uri']. - * Such syntax can be used by external code, for instance, for testing. -configs[0].module.rules.push({ - test: /\.js$/, - loader: require.resolve('@theia/application-manager/lib/expose-loader') -}); */ - -module.exports = configs; diff --git a/examples/browser/esbuild.mjs b/examples/browser/esbuild.mjs new file mode 100644 index 0000000000000..fab65db5a34db --- /dev/null +++ b/examples/browser/esbuild.mjs @@ -0,0 +1,30 @@ +/** + * This file can be edited to the ESBuild build process. + * To reset, delete this file and rerun theia build again. + */ +import { browserOptions, watch } from './gen-esbuild.browser.mjs'; +import { nodeOptions } from './gen-esbuild.node.mjs'; +import esbuild from 'esbuild'; + +const browserContext = await esbuild.context(browserOptions); +const nodeContext = await esbuild.context(nodeOptions); + +if (watch) { + await Promise.all([ + browserContext.watch(), + nodeContext.watch() + ]); +} else { + try { + await Promise.all([ + browserContext.rebuild(), + nodeContext.rebuild() + ]); + await Promise.all([ + browserContext.dispose(), + nodeContext.dispose() + ]); + } catch (err) { + process.exit(1); + } +} diff --git a/examples/browser/webpack.config.js b/examples/browser/webpack.config.js deleted file mode 100644 index 69246fc75b5cd..0000000000000 --- a/examples/browser/webpack.config.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * This file can be edited to customize webpack configuration. - * To reset delete this file and rerun theia build again. - */ -// @ts-check -const configs = require('./gen-webpack.config.js'); -const nodeConfig = require('./gen-webpack.node.config.js'); - -/** - * Expose bundled modules on window.theia.moduleName namespace, e.g. - * window['theia']['@theia/core/lib/common/uri']. - * Such syntax can be used by external code, for instance, for testing. - */ -configs[0].module.rules.push({ - test: /\.js$/, - loader: require.resolve('@theia/application-manager/lib/expose-loader') -}); - -module.exports = [ - ...configs, - nodeConfig.config -]; diff --git a/examples/electron/esbuild.mjs b/examples/electron/esbuild.mjs new file mode 100644 index 0000000000000..a512772aba3ef --- /dev/null +++ b/examples/electron/esbuild.mjs @@ -0,0 +1,35 @@ +/** + * This file can be edited to the ESBuild build process. + * To reset, delete this file and rerun theia build again. + */ +import { browserOptions, watch } from './gen-esbuild.browser.mjs'; +import { nodeOptions } from './gen-esbuild.node.mjs'; +import { electronOptions } from './gen-esbuild.electron.mjs'; +import esbuild from 'esbuild'; + +const browserContext = await esbuild.context(browserOptions); +const nodeContext = await esbuild.context(nodeOptions); +const electronContext = await esbuild.context(electronOptions); + +if (watch) { + await Promise.all([ + browserContext.watch(), + nodeContext.watch(), + electronContext.watch(), + ]); +} else { + try { + await Promise.all([ + browserContext.rebuild(), + nodeContext.rebuild(), + electronContext.rebuild(), + ]); + await Promise.all([ + browserContext.dispose(), + nodeContext.dispose(), + electronContext.dispose(), + ]); + } catch (err) { + process.exit(1); + } +} diff --git a/examples/electron/webpack.config.js b/examples/electron/webpack.config.js deleted file mode 100644 index 8c8bfd55c3b64..0000000000000 --- a/examples/electron/webpack.config.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * This file can be edited to customize webpack configuration. - * To reset delete this file and rerun theia build again. - */ -// @ts-check -const configs = require('./gen-webpack.config.js'); -const nodeConfig = require('./gen-webpack.node.config.js'); - -/** - * Expose bundled modules on window.theia.moduleName namespace, e.g. - * window['theia']['@theia/core/lib/common/uri']. - * Such syntax can be used by external code, for instance, for testing. -config.module.rules.push({ - test: /\.js$/, - loader: require.resolve('@theia/application-manager/lib/expose-loader') -}); */ - -module.exports = [ - ...configs, - nodeConfig.config -]; diff --git a/package-lock.json b/package-lock.json index 45c0ad2a529a8..27a9c0bf0bfa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,6 +75,7 @@ "@babel/preset-env": "^7.10.0", "@theia/application-package": "1.57.0", "@theia/ffmpeg": "1.57.0", + "@theia/native-esbuild-plugin": "1.57.0", "@theia/native-webpack-plugin": "1.57.0", "@types/fs-extra": "^4.0.2", "@types/semver": "^7.5.0", @@ -84,6 +85,9 @@ "copy-webpack-plugin": "^8.1.1", "css-loader": "^6.2.0", "electron-rebuild": "^3.2.7", + "esbuild": "^0.24.0", + "esbuild-plugin-copy": "^2.1.1", + "esbuild-plugins-node-modules-polyfill": "^1.6.7", "fs-extra": "^4.0.2", "http-server": "^14.1.1", "ignore-loader": "^0.1.2", @@ -296,6 +300,25 @@ "@theia/ext-scripts": "1.57.0" } }, + "dev-packages/native-esbuild-plugin": { + "name": "@theia/native-esbuild-plugin", + "version": "1.57.0", + "license": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0", + "dependencies": { + "detect-libc": "^2.0.2", + "tslib": "^2.6.2", + "webpack": "^5.76.0" + } + }, + "dev-packages/native-esbuild-plugin/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "dev-packages/native-webpack-plugin": { "name": "@theia/native-webpack-plugin", "version": "1.57.0", @@ -2955,6 +2978,406 @@ "node": ">= 4.0.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -3537,6 +3960,11 @@ "url": "https://opencollective.com/js-sdsl" } }, + "node_modules/@jspm/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@jspm/core/-/core-2.0.1.tgz", + "integrity": "sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==" + }, "node_modules/@lerna/child-process": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-7.4.2.tgz", @@ -6093,6 +6521,10 @@ "integrity": "sha512-UaAi6CEvain/qbGD3o6Ufe8plLyzAVQ53p9Ke+MoBYDhb391+r+MuK++JtITqIrXqoa8OCjbt8wQxEFSNNO0Mw==", "license": "MIT and (Apache-2.0 or MPL-2.0)" }, + "node_modules/@theia/native-esbuild-plugin": { + "resolved": "dev-packages/native-esbuild-plugin", + "link": true + }, "node_modules/@theia/native-webpack-plugin": { "resolved": "dev-packages/native-webpack-plugin", "link": true @@ -10814,6 +11246,12 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -13276,6 +13714,108 @@ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", "license": "MIT" }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/esbuild-plugin-copy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/esbuild-plugin-copy/-/esbuild-plugin-copy-2.1.1.tgz", + "integrity": "sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "fs-extra": "^10.0.1", + "globby": "^11.0.3" + }, + "peerDependencies": { + "esbuild": ">= 0.14.0" + } + }, + "node_modules/esbuild-plugin-copy/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/esbuild-plugin-copy/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-plugins-node-modules-polyfill": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/esbuild-plugins-node-modules-polyfill/-/esbuild-plugins-node-modules-polyfill-1.6.8.tgz", + "integrity": "sha512-bRB4qbgUDWrdY1eMk123KiaCSW9VzQ+QLZrmU7D//cCFkmksPd9mUMpmWoFK/rxjIeTfTSOpKCoGoimlvI+AWw==", + "license": "MIT", + "dependencies": { + "@jspm/core": "2.0.1", + "local-pkg": "^0.5.0", + "resolve.exports": "^2.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.14.0 <=0.24.x" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -17336,12 +17876,6 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", - "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", - "license": "MIT" - }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -18298,6 +18832,22 @@ "node": ">=8.9.0" } }, + "node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "license": "MIT", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -19372,6 +19922,18 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT" }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, "node_modules/mocha": { "version": "10.8.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", @@ -22531,6 +23093,12 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.1.tgz", + "integrity": "sha512-6jpjMpOth5S9ITVu5clZ7NOgHNsv5vRQdheL9ztp2vZmM6fRbLvyua1tiBIL4lk8SAe3ARzeXEly6siXCjDHDw==", + "license": "MIT" + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -22693,6 +23261,17 @@ "node": ">=8" } }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -24464,6 +25043,15 @@ "node": ">= 12" } }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/responselike": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", @@ -28030,6 +28618,12 @@ "dev": true, "license": "MIT" }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "license": "MIT" + }, "node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", @@ -30412,7 +31006,7 @@ "@theia/workspace": "1.57.0", "@vscode/debugprotocol": "^1.51.0", "fast-deep-equal": "^3.1.3", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "p-debounce": "^2.1.0", "tslib": "^2.6.2" }, @@ -30420,6 +31014,12 @@ "@theia/ext-scripts": "1.57.0" } }, + "packages/debug/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/dev-container": { "name": "@theia/dev-container", "version": "1.57.0", @@ -30430,7 +31030,7 @@ "@theia/remote": "1.57.0", "@theia/workspace": "1.57.0", "dockerode": "^4.0.2", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "uuid": "^8.0.0" }, "devDependencies": { @@ -30438,6 +31038,12 @@ "@types/dockerode": "^3.3.23" } }, + "packages/dev-container/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/dev-container/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -30659,13 +31265,19 @@ "@theia/monaco-editor-core": "1.83.101", "@theia/preferences": "1.57.0", "@theia/userstorage": "1.57.0", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "tslib": "^2.6.2" }, "devDependencies": { "@theia/ext-scripts": "1.57.0" } }, + "packages/keymaps/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/markers": { "name": "@theia/markers", "version": "1.57.0", @@ -30753,7 +31365,7 @@ "@theia/workspace": "1.57.0", "fast-plist": "^0.1.2", "idb": "^4.0.5", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "tslib": "^2.6.2", "vscode-oniguruma": "1.6.1", "vscode-textmate": "^9.0.0" @@ -30762,6 +31374,12 @@ "@theia/ext-scripts": "1.57.0" } }, + "packages/monaco/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/navigator": { "name": "@theia/navigator", "version": "1.57.0", @@ -30937,7 +31555,7 @@ "escape-html": "^1.0.3", "filenamify": "^4.1.0", "is-electron": "^2.2.0", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "lodash.clonedeep": "^4.5.0", "macaddress": "^0.5.3", "mime": "^2.4.4", @@ -31006,6 +31624,12 @@ "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==", "license": "MIT" }, + "packages/plugin-ext/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/plugin-metrics": { "name": "@theia/plugin-metrics", "version": "1.57.0", @@ -31036,7 +31660,7 @@ "@theia/workspace": "1.57.0", "async-mutex": "^0.3.1", "fast-deep-equal": "^3.1.3", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "p-debounce": "^2.1.0", "tslib": "^2.6.2" }, @@ -31053,6 +31677,12 @@ "tslib": "^2.3.1" } }, + "packages/preferences/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/preview": { "name": "@theia/preview", "version": "1.57.0", @@ -31322,7 +31952,7 @@ "@theia/variable-resolver": "1.57.0", "@theia/workspace": "1.57.0", "async-mutex": "^0.3.1", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "p-debounce": "^2.1.0", "tslib": "^2.6.2" }, @@ -31339,6 +31969,12 @@ "tslib": "^2.3.1" } }, + "packages/task/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/terminal": { "name": "@theia/terminal", "version": "1.57.0", @@ -31422,11 +32058,17 @@ "@theia/userstorage": "1.57.0", "@theia/workspace": "1.57.0", "ajv": "^6.5.3", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "perfect-scrollbar": "^1.5.5", "tslib": "^2.6.2" } }, + "packages/toolbar/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "packages/typehierarchy": { "name": "@theia/typehierarchy", "version": "1.57.0", @@ -31497,7 +32139,7 @@ "@theia/core": "1.57.0", "@theia/filesystem": "1.57.0", "@theia/variable-resolver": "1.57.0", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "tslib": "^2.6.2", "valid-filename": "^2.0.1" }, @@ -31505,6 +32147,12 @@ "@theia/ext-scripts": "1.57.0" } }, + "packages/workspace/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, "sample-plugins/sample-namespace/plugin-a": { "version": "1.57.0", "license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0", diff --git a/packages/ai-mcp/src/node/mcp-server.ts b/packages/ai-mcp/src/node/mcp-server.ts index 52a7932762df7..58bc5e4e74020 100644 --- a/packages/ai-mcp/src/node/mcp-server.ts +++ b/packages/ai-mcp/src/node/mcp-server.ts @@ -13,7 +13,7 @@ // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio'; +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; export class MCPServer { diff --git a/packages/core/src/browser/frontend-application-module.ts b/packages/core/src/browser/frontend-application-module.ts index ea29eff0ebf87..ebde45ba17000 100644 --- a/packages/core/src/browser/frontend-application-module.ts +++ b/packages/core/src/browser/frontend-application-module.ts @@ -15,9 +15,11 @@ // ***************************************************************************** import '../../src/browser/style/index.css'; -require('../../src/browser/style/materialcolors.css').use(); +import '../../src/browser/style/materialcolors.css'; +import '@phosphor/widgets/style/index.css'; import 'font-awesome/css/font-awesome.min.css'; import 'file-icons-js/css/style.css'; +import 'perfect-scrollbar/css/perfect-scrollbar.css'; import '@vscode/codicons/dist/codicon.css'; import { ContainerModule } from 'inversify'; diff --git a/packages/core/src/browser/style/index.css b/packages/core/src/browser/style/index.css index 3a69dc7c2c1c6..3bacbf9212e4c 100644 --- a/packages/core/src/browser/style/index.css +++ b/packages/core/src/browser/style/index.css @@ -14,8 +14,33 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 ********************************************************************************/ -@import url("~@phosphor/widgets/style/index.css"); -@import url("~font-awesome/css/font-awesome.min.css"); +/*----------------------------------------------------------------------------- +| Import children style files +|----------------------------------------------------------------------------*/ + +@import "./os.css"; +@import "./dockpanel.css"; +@import "./dialog.css"; +@import "./menus.css"; +@import "./sidepanel.css"; +@import "./tabs.css"; +@import "./scrollbars.css"; +@import "./tree.css"; +@import "./status-bar.css"; +@import "./tree-decorators.css"; +@import "./about.css"; +@import "./search-box.css"; +@import "./ansi.css"; +@import "./view-container.css"; +@import "./notification.css"; +@import "./alert-messages.css"; +@import "./icons.css"; +@import "./widget.css"; +@import "./quick-title-bar.css"; +@import "./progress-bar.css"; +@import "./breadcrumbs.css"; +@import "./tooltip.css"; +@import "./split-widget.css"; /*----------------------------------------------------------------------------- | General @@ -161,6 +186,7 @@ blockquote { right: 0; bottom: 0; background: var(--theia-editor-background); + height: 100%; } .theia-preload { @@ -323,31 +349,3 @@ button.secondary[disabled], .theia-cursor-no-drop:active { cursor: no-drop; } - -/*----------------------------------------------------------------------------- -| Import children style files -|----------------------------------------------------------------------------*/ - -@import "./os.css"; -@import "./dockpanel.css"; -@import "./dialog.css"; -@import "./menus.css"; -@import "./sidepanel.css"; -@import "./tabs.css"; -@import "./scrollbars.css"; -@import "./tree.css"; -@import "./status-bar.css"; -@import "./tree-decorators.css"; -@import "./about.css"; -@import "./search-box.css"; -@import "./ansi.css"; -@import "./view-container.css"; -@import "./notification.css"; -@import "./alert-messages.css"; -@import "./icons.css"; -@import "./widget.css"; -@import "./quick-title-bar.css"; -@import "./progress-bar.css"; -@import "./breadcrumbs.css"; -@import "./tooltip.css"; -@import "./split-widget.css"; diff --git a/packages/core/src/browser/style/scrollbars.css b/packages/core/src/browser/style/scrollbars.css index 17e96058a76d6..f9b6b5b840422 100644 --- a/packages/core/src/browser/style/scrollbars.css +++ b/packages/core/src/browser/style/scrollbars.css @@ -14,8 +14,6 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 ********************************************************************************/ -@import url("~perfect-scrollbar/css/perfect-scrollbar.css"); - ::-webkit-scrollbar { height: var(--theia-scrollbar-width); width: var(--theia-scrollbar-width); diff --git a/packages/debug/package.json b/packages/debug/package.json index afbfb9435e917..62d59b76a811f 100644 --- a/packages/debug/package.json +++ b/packages/debug/package.json @@ -19,7 +19,7 @@ "@theia/workspace": "1.57.0", "@vscode/debugprotocol": "^1.51.0", "fast-deep-equal": "^3.1.3", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "p-debounce": "^2.1.0", "tslib": "^2.6.2" }, diff --git a/packages/dev-container/package.json b/packages/dev-container/package.json index bdb0b4545f568..89d4175687b14 100644 --- a/packages/dev-container/package.json +++ b/packages/dev-container/package.json @@ -8,7 +8,7 @@ "@theia/remote": "1.57.0", "@theia/workspace": "1.57.0", "dockerode": "^4.0.2", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "uuid": "^8.0.0" }, "publishConfig": { diff --git a/packages/git/src/browser/history/git-history-frontend-module.ts b/packages/git/src/browser/history/git-history-frontend-module.ts index 749f0bda92db3..20c88cfa26c77 100644 --- a/packages/git/src/browser/history/git-history-frontend-module.ts +++ b/packages/git/src/browser/history/git-history-frontend-module.ts @@ -25,7 +25,6 @@ import { GitScmProvider } from '../git-scm-provider'; import { createScmTreeContainer } from '@theia/scm/lib/browser/scm-frontend-module'; import { GitResourceOpener } from '../diff/git-resource-opener'; import { GitOpenerInSecondaryArea } from './git-opener-in-secondary-area'; -import '../../../src/browser/style/git-icons.css'; export function bindGitHistoryModule(bind: interfaces.Bind): void { diff --git a/packages/git/src/browser/style/git-diff.svg b/packages/git/src/browser/style/git-diff.svg deleted file mode 100644 index 262a9b3f00af5..0000000000000 --- a/packages/git/src/browser/style/git-diff.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/packages/git/src/browser/style/git-icons.css b/packages/git/src/browser/style/git-icons.css deleted file mode 100644 index a9a4409ae64a0..0000000000000 --- a/packages/git/src/browser/style/git-icons.css +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2018 TypeFox and others. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the Eclipse - * Public License v. 2.0 are satisfied: GNU General Public License, version 2 - * with the GNU Classpath Exception which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 - ********************************************************************************/ - -.icon-git-commit { - mask-repeat: no-repeat; - mask-position: center; - -webkit-mask-repeat: no-repeat; - -webkit-mask-position: center; - mask-image: url("~octicons/build/svg/git-commit.svg"); - -webkit-mask-image: url("~octicons/build/svg/git-commit.svg"); -} diff --git a/packages/git/src/browser/style/git.svg b/packages/git/src/browser/style/git.svg deleted file mode 100644 index 9280ae1dbf89d..0000000000000 --- a/packages/git/src/browser/style/git.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/packages/keymaps/package.json b/packages/keymaps/package.json index 302779ca8372b..98bd8a62353ad 100644 --- a/packages/keymaps/package.json +++ b/packages/keymaps/package.json @@ -8,7 +8,7 @@ "@theia/monaco-editor-core": "1.83.101", "@theia/preferences": "1.57.0", "@theia/userstorage": "1.57.0", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "tslib": "^2.6.2" }, "devDependencies": { diff --git a/packages/monaco/package.json b/packages/monaco/package.json index af1af5c0f3d72..b630c3df70a2f 100644 --- a/packages/monaco/package.json +++ b/packages/monaco/package.json @@ -12,7 +12,7 @@ "@theia/workspace": "1.57.0", "fast-plist": "^0.1.2", "idb": "^4.0.5", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "tslib": "^2.6.2", "vscode-oniguruma": "1.6.1", "vscode-textmate": "^9.0.0" diff --git a/packages/plugin-ext-headless/src/hosted/node/plugin-ext-headless-hosted-module.ts b/packages/plugin-ext-headless/src/hosted/node/plugin-ext-headless-hosted-module.ts index 3e651eee6bedc..a563dd2631a23 100644 --- a/packages/plugin-ext-headless/src/hosted/node/plugin-ext-headless-hosted-module.ts +++ b/packages/plugin-ext-headless/src/hosted/node/plugin-ext-headless-hosted-module.ts @@ -52,10 +52,10 @@ export function bindHeadlessHosted(bind: interfaces.Bind): void { bind(PluginScanner).toService(TheiaHeadlessPluginScanner); bind(SupportedHeadlessActivationEvents).toConstantValue(['*', 'onStartupFinished']); - bind(BackendApplicationContribution).toDynamicValue(({container}) => { + bind(BackendApplicationContribution).toDynamicValue(({ container }) => { let hostedPluginSupport: HeadlessHostedPluginSupport | undefined; - return { + return new class HeadlessHostedPluginBackendContribution implements BackendApplicationContribution { onStart(): MaybePromise { // Create a child container to isolate the Headless Plugin hosting stack // from all connection-scoped frontend/backend plugin hosts and @@ -66,11 +66,10 @@ export function bindHeadlessHosted(bind: interfaces.Bind): void { hostedPluginSupport = headlessPluginsContainer.get(HeadlessHostedPluginSupport); hostedPluginSupport.onStart(headlessPluginsContainer); - }, - + } onStop(): void { hostedPluginSupport?.shutDown(); } - }; + }(); }); } diff --git a/packages/plugin-ext/package.json b/packages/plugin-ext/package.json index 73a77bf958aa3..e68089d86ada1 100644 --- a/packages/plugin-ext/package.json +++ b/packages/plugin-ext/package.json @@ -40,7 +40,7 @@ "escape-html": "^1.0.3", "filenamify": "^4.1.0", "is-electron": "^2.2.0", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "lodash.clonedeep": "^4.5.0", "macaddress": "^0.5.3", "mime": "^2.4.4", diff --git a/packages/plugin-ext/src/hosted/browser/plugin-worker.ts b/packages/plugin-ext/src/hosted/browser/plugin-worker.ts index e500140a553f5..9ad56e366e04a 100644 --- a/packages/plugin-ext/src/hosted/browser/plugin-worker.ts +++ b/packages/plugin-ext/src/hosted/browser/plugin-worker.ts @@ -27,9 +27,8 @@ export class PluginWorker { constructor() { this.worker = new Worker(new URL('./worker/worker-main', - // @ts-expect-error (TS1343) // We compile to CommonJS but `import.meta` is still available in the browser - import.meta.url)); + '')); const channel = new BasicChannel(() => { const writer = new Uint8ArrayWriteBuffer(); diff --git a/packages/plugin-ext/src/main/browser/style/index.css b/packages/plugin-ext/src/main/browser/style/index.css index a8ba00ae4400d..c677693d23f95 100644 --- a/packages/plugin-ext/src/main/browser/style/index.css +++ b/packages/plugin-ext/src/main/browser/style/index.css @@ -14,6 +14,10 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 ********************************************************************************/ +@import "./plugin-sidebar.css"; +@import "./webview.css"; +@import "./tree.css"; + .spinnerContainer { width: 100%; height: 100%; @@ -78,7 +82,3 @@ background-size: var(--theia-private-sidebar-icon-size) !important; font-size: var(--theia-private-sidebar-icon-size) !important; } - -@import "./plugin-sidebar.css"; -@import "./webview.css"; -@import "./tree.css"; diff --git a/packages/plugin-ext/src/main/browser/webview/pre/fake.html b/packages/plugin-ext/src/main/browser/webview/pre/fake.html index 18c40421e34bc..3b2f95d78dc1e 100644 --- a/packages/plugin-ext/src/main/browser/webview/pre/fake.html +++ b/packages/plugin-ext/src/main/browser/webview/pre/fake.html @@ -1,6 +1,8 @@ +Test + diff --git a/packages/preferences/package.json b/packages/preferences/package.json index bbc9c030ae2f8..15ae032f5f19b 100644 --- a/packages/preferences/package.json +++ b/packages/preferences/package.json @@ -12,7 +12,7 @@ "@theia/workspace": "1.57.0", "async-mutex": "^0.3.1", "fast-deep-equal": "^3.1.3", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "p-debounce": "^2.1.0", "tslib": "^2.6.2" }, diff --git a/packages/preferences/src/browser/style/index.css b/packages/preferences/src/browser/style/index.css index dd598700451c9..db99fa3e63367 100644 --- a/packages/preferences/src/browser/style/index.css +++ b/packages/preferences/src/browser/style/index.css @@ -14,6 +14,12 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 ********************************************************************************/ +@import url("./preference-context-menu.css"); +@import url("./preference-array.css"); +@import url("./preference-file.css"); +@import url("./preference-object.css"); +@import url("./search-input.css"); + #preferences_container_widget .p-SplitPanel-handle { border-right: var(--theia-border-width) solid var(--theia-editorGroup-border); } @@ -26,12 +32,6 @@ /* UI View */ -@import url("./preference-context-menu.css"); -@import url("./preference-array.css"); -@import url("./preference-file.css"); -@import url("./preference-object.css"); -@import url("./search-input.css"); - .theia-settings-container { max-width: 1000px; padding-top: 11px; diff --git a/packages/task/package.json b/packages/task/package.json index 22b43b1a53e91..3bbffe60001ac 100644 --- a/packages/task/package.json +++ b/packages/task/package.json @@ -15,7 +15,7 @@ "@theia/variable-resolver": "1.57.0", "@theia/workspace": "1.57.0", "async-mutex": "^0.3.1", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "p-debounce": "^2.1.0", "tslib": "^2.6.2" }, diff --git a/packages/test/src/browser/view/test-tree-widget.tsx b/packages/test/src/browser/view/test-tree-widget.tsx index 3c5e0c7852bb7..2cca19467d4e2 100644 --- a/packages/test/src/browser/view/test-tree-widget.tsx +++ b/packages/test/src/browser/view/test-tree-widget.tsx @@ -274,7 +274,6 @@ export class TestTreeWidget extends TreeWidget { case TestExecutionState.Failed: return `${codicon('error')} failed`; case TestExecutionState.Errored: return `${codicon('issues')} errored`; case TestExecutionState.Passed: return `${codicon('pass')} passed`; - case TestExecutionState.Running: return `${codicon('sync-spin')} running`; default: return codicon('circle'); } } diff --git a/packages/toolbar/package.json b/packages/toolbar/package.json index 27f20050e57d0..df9353403278a 100644 --- a/packages/toolbar/package.json +++ b/packages/toolbar/package.json @@ -37,7 +37,7 @@ "@theia/userstorage": "1.57.0", "@theia/workspace": "1.57.0", "ajv": "^6.5.3", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "perfect-scrollbar": "^1.5.5", "tslib": "^2.6.2" }, diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 4d2112ac26a2f..ebf9847616f7a 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -6,7 +6,7 @@ "@theia/core": "1.57.0", "@theia/filesystem": "1.57.0", "@theia/variable-resolver": "1.57.0", - "jsonc-parser": "^2.2.0", + "jsonc-parser": "^3.3.1", "tslib": "^2.6.2", "valid-filename": "^2.0.1" },