diff --git a/.vscode/settings.json b/.vscode/settings.json index 2b67a978..20d862b7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,9 @@ "eslint.codeAction.showDocumentation": { "enable": true }, + "[typescript]": { + "editor.defaultFormatter": null + }, "eslint.validate": [ "javascript", "typescript" diff --git a/demo/package-lock.json b/demo/package-lock.json index 0a36275c..16089b31 100644 --- a/demo/package-lock.json +++ b/demo/package-lock.json @@ -32,6 +32,7 @@ "@codingame/monaco-vscode-emmet-default-extension": "file:../dist/default-extension-emmet", "@codingame/monaco-vscode-environment-service-override": "file:../dist/service-override-environment", "@codingame/monaco-vscode-extension-editing-default-extension": "file:../dist/default-extension-extension-editing", + "@codingame/monaco-vscode-extension-gallery-service-override": "file:../dist/service-override-extension-gallery", "@codingame/monaco-vscode-extensions-service-override": "file:../dist/service-override-extensions", "@codingame/monaco-vscode-files-service-override": "file:../dist/service-override-files", "@codingame/monaco-vscode-fsharp-default-extension": "file:../dist/default-extension-fsharp", @@ -989,6 +990,15 @@ "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" } }, + "../dist/service-override-extension-gallery": { + "name": "@codingame/monaco-vscode-extension-gallery-service-override", + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, "../dist/service-override-extensions": { "name": "@codingame/monaco-vscode-extensions-service-override", "version": "0.0.0-semantic-release", @@ -1433,6 +1443,10 @@ "resolved": "../dist/default-extension-extension-editing", "link": true }, + "node_modules/@codingame/monaco-vscode-extension-gallery-service-override": { + "resolved": "../dist/service-override-extension-gallery", + "link": true + }, "node_modules/@codingame/monaco-vscode-extensions-service-override": { "resolved": "../dist/service-override-extensions", "link": true diff --git a/demo/package.json b/demo/package.json index a17fffc4..f047adc7 100644 --- a/demo/package.json +++ b/demo/package.json @@ -52,6 +52,7 @@ "@codingame/monaco-vscode-editor-service-override": "file:../dist/service-override-editor", "@codingame/monaco-vscode-emmet-default-extension": "file:../dist/default-extension-emmet", "@codingame/monaco-vscode-environment-service-override": "file:../dist/service-override-environment", + "@codingame/monaco-vscode-extension-gallery-service-override": "file:../dist/service-override-extension-gallery", "@codingame/monaco-vscode-extension-editing-default-extension": "file:../dist/default-extension-extension-editing", "@codingame/monaco-vscode-extensions-service-override": "file:../dist/service-override-extensions", "@codingame/monaco-vscode-files-service-override": "file:../dist/service-override-files", diff --git a/demo/src/setup.ts b/demo/src/setup.ts index 6b268ec0..d4aa4c16 100644 --- a/demo/src/setup.ts +++ b/demo/src/setup.ts @@ -9,6 +9,7 @@ import getTextmateServiceOverride from '@codingame/monaco-vscode-textmate-servic import getThemeServiceOverride from '@codingame/monaco-vscode-theme-service-override' import getLanguagesServiceOverride from '@codingame/monaco-vscode-languages-service-override' import getAudioCueServiceOverride from '@codingame/monaco-vscode-audio-cue-service-override' +import getExtensionGalleryServiceOverride from '@codingame/monaco-vscode-extension-gallery-service-override' import getViewsServiceOverride, { isEditorPartVisible, Parts, @@ -104,6 +105,7 @@ await Promise.all([ // Override services await initializeMonacoService({ ...getExtensionServiceOverride(toWorkerConfig(ExtensionHostWorker)), + ...getExtensionGalleryServiceOverride(), ...getModelServiceOverride(), ...getNotificationServiceOverride(), ...getDialogsServiceOverride(), @@ -137,7 +139,18 @@ await initializeMonacoService({ ...getLifecycleServiceOverride(), ...getEnvironmentServiceOverride({ remoteAuthority, - enableWorkspaceTrust: true + enableWorkspaceTrust: true, + productConfiguration: { + extensionsGallery: { + serviceUrl: 'https://open-vsx.org/vscode/gallery', + itemUrl: 'https://open-vsx.org/vscode/item', + resourceUrlTemplate: 'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}', + controlUrl: '', + recommendationsUrl: '', + nlsBaseUrl: '', + publisherUrl: '' + } + } }), ...getWorkspaceTrustOverride() }) diff --git a/package-lock.json b/package-lock.json index 92ee8216..8b365dd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -87,7 +87,7 @@ "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.1.0", "rollup-plugin-styles": "^4.0.0", - "semver": "^7.5.4", + "semver": "^5.7.2", "ts-morph": "^20.0.0", "ts-node": "^10.9.1", "type-fest": "^4.4.0", @@ -2986,9 +2986,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", + "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==", "dev": true }, "node_modules/@types/vscode": { @@ -3047,6 +3047,39 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/parser": { "version": "6.7.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", @@ -3159,6 +3192,39 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/utils": { "version": "6.7.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", @@ -3184,6 +3250,39 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.7.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", @@ -3805,6 +3904,39 @@ "semver": "^7.0.0" } }, + "node_modules/builtins/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/builtins/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/cacheable-lookup": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", @@ -4833,6 +4965,39 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-plugin-n/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-n/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/eslint-plugin-promise": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", @@ -6772,6 +6937,36 @@ "node": ">=10" } }, + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/node-addon-api": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", @@ -7105,6 +7300,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/package-json/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -7278,6 +7506,18 @@ "node": ">=8" } }, + "node_modules/patch-package/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/patch-package/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -7290,6 +7530,21 @@ "rimraf": "bin.js" } }, + "node_modules/patch-package/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/patch-package/node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -7311,6 +7566,12 @@ "node": ">=8" } }, + "node_modules/patch-package/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -8579,35 +8840,14 @@ } }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "semver": "bin/semver" } }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index a707da7a..6d118c2e 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.1.0", "rollup-plugin-styles": "^4.0.0", - "semver": "^7.5.4", + "semver": "^5.7.2", "ts-morph": "^20.0.0", "ts-node": "^10.9.1", "type-fest": "^4.4.0", diff --git a/rollup/rollup.config.ts b/rollup/rollup.config.ts index 375597e4..597d1c07 100644 --- a/rollup/rollup.config.ts +++ b/rollup/rollup.config.ts @@ -496,6 +496,7 @@ const workerGroups: Record = { const externals = Object.keys({ ...pkg.dependencies }) const external: rollup.ExternalOption = (source) => { + if (source === 'semver' || source.startsWith('semver')) return true if (source.includes('tas-client-umd')) return true if (source.startsWith(MONACO_EDITOR_DIR) || source.startsWith('monaco-editor/')) { return true diff --git a/rollup/rollup.server.config.ts b/rollup/rollup.server.config.ts index 8cfacd67..2c722959 100644 --- a/rollup/rollup.server.config.ts +++ b/rollup/rollup.server.config.ts @@ -4,6 +4,7 @@ import typescript from '@rollup/plugin-typescript' import commonjs from '@rollup/plugin-commonjs' import json from '@rollup/plugin-json' import { PackageJson } from 'type-fest' +import * as fs from 'fs/promises' import * as path from 'path' import { fileURLToPath } from 'url' import metadataPlugin from './rollup-metadata-plugin.js' @@ -14,6 +15,12 @@ const EXTENSIONS = ['', '.ts', '.js'] const BASE_DIR = path.resolve(__dirname, '..') const TSCONFIG = path.resolve(BASE_DIR, 'tsconfig.rollup.json') +const dir = 'dist/server' + +// We need to create an empty "extensions" folder so the vscode server can use that +// directory to search for system extensions +await fs.mkdir('dist/server/extensions', { recursive: true }) + const externals = Object.keys(pkg.dependencies) const config: rollup.RollupOptions = { cache: false, @@ -26,7 +33,7 @@ const config: rollup.RollupOptions = { }, output: [{ format: 'esm', - dir: 'dist/server', + dir, entryFileNames: '[name].js', chunkFileNames: '[name].js', banner: (module) => module.isEntry ? '#!/usr/bin/env node' : '' diff --git a/scripts/vscode.patch b/scripts/vscode.patch index 5dc19ffb..23be8027 100644 --- a/scripts/vscode.patch +++ b/scripts/vscode.patch @@ -1582,6 +1582,19 @@ index f4707432371..7c5cdde39cc 100644 declare _serviceBrand: undefined; +diff --git a/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts b/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts +index a466cc1f3a1..09f6a40eb26 100644 +--- a/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts ++++ b/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts +@@ -16,7 +16,7 @@ import { ILogService } from 'vs/platform/log/common/log'; + import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; + import { IActiveLanguagePackService } from 'vs/workbench/services/localization/common/locale'; + +-class RemoteExtensionsScannerService implements IRemoteExtensionsScannerService { ++export class RemoteExtensionsScannerService implements IRemoteExtensionsScannerService { + + declare readonly _serviceBrand: undefined; + diff --git a/src/vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts b/src/vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts index 850b58e1e6c..2eb835fa2b6 100644 --- a/src/vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts @@ -1750,6 +1763,19 @@ index ad67fb4f422..fadf86cece5 100644 // ensure to limit buffer for guessing due to https://github.com/aadsm/jschardet/issues/53 const limitedBuffer = buffer.slice(0, AUTO_ENCODING_GUESS_MAX_BYTES); +diff --git a/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts b/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts +index d3ef612836b..0d0fb8d2862 100644 +--- a/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts ++++ b/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts +@@ -25,7 +25,7 @@ export interface IRemoteUserDataProfilesService { + getRemoteProfile(localProfile: IUserDataProfile): Promise; + } + +-class RemoteUserDataProfilesService extends Disposable implements IRemoteUserDataProfilesService { ++export class RemoteUserDataProfilesService extends Disposable implements IRemoteUserDataProfilesService { + + readonly _serviceBrand: undefined; + diff --git a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts b/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts index 4653e395be9..1eccfce4bf4 100644 --- a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts diff --git a/src/missing-services.ts b/src/missing-services.ts index 315517bc..e2e031ca 100644 --- a/src/missing-services.ts +++ b/src/missing-services.ts @@ -55,7 +55,7 @@ import { IEditSessionIdentityService } from 'vs/platform/workspace/common/editSe import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing' import { ITimerService } from 'vs/workbench/services/timer/browser/timerService' import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions' -import { EnablementState, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement' +import { EnablementState, IExtensionManagementServerService, IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement' import { ITunnelService } from 'vs/platform/tunnel/common/tunnel' import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup' import { IWorkingCopyService, WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService' @@ -94,7 +94,7 @@ import { IBreadcrumbsService } from 'vs/workbench/browser/parts/editor/breadcrum import { IOutlineService } from 'vs/workbench/services/outline/browser/outline' import { IUpdateService, State } from 'vs/platform/update/common/update' import { IStatusbarService } from 'vs/workbench/services/statusbar/browser/statusbar' -import { IExtensionGalleryService, IExtensionManagementService, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement' +import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement' import { IModelService } from 'vs/editor/common/services/model' import { IDetachedTerminalInstance, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalService, TerminalConnectionState } from 'vs/workbench/contrib/terminal/browser/terminal' import { ITerminalProfileResolverService, ITerminalProfileService } from 'vs/workbench/contrib/terminal/common/terminal' @@ -105,7 +105,7 @@ import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/commo import { ITerminalQuickFixService } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix' import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences' import { AccountStatus, IUserDataSyncWorkbenchService } from 'vs/workbench/services/userDataSync/common/userDataSync' -import { IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync' +import { IUserDataAutoSyncService, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync' import { IKeybindingEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing' import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService' import { ISearchHistoryService } from 'vs/workbench/contrib/search/common/searchHistoryService' @@ -129,7 +129,7 @@ import { IEditorDropService } from 'vs/workbench/services/editor/browser/editorD import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver' import { ExternalUriOpenerService, IExternalUriOpenerService } from 'vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService' import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView' -import { IExtension, IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions' +import { IBuiltinExtensionsScannerService, IExtension, IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions' import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService' import { IRemoteExtensionsScannerService } from 'vs/platform/remote/common/remoteExtensionsScanner' import { BrowserURLService } from 'vs/workbench/services/url/browser/urlService' @@ -172,9 +172,17 @@ import { BrowserHostService } from 'vs/workbench/services/host/browser/browserHo import { IBannerService } from 'vs/workbench/services/banner/browser/bannerService' import { ITitleService } from 'vs/workbench/services/title/common/titleService' import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents' +import { IActiveLanguagePackService, ILocaleService } from 'vs/workbench/services/localization/common/locale' import { joinPath } from 'vs/base/common/resources' import { unsupported } from './tools' import { getBuiltInExtensionTranslationsUris } from './l10n' +import { IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations' +import { IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions' +import { IExtensionRecommendationNotificationService } from 'vs/platform/extensionRecommendations/common/extensionRecommendations' +import { IWorkspaceExtensionsConfigService } from 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig' +import { IRemoteUserDataProfilesService } from 'vs/workbench/services/userDataProfile/common/remoteUserDataProfiles' +import { IExtensionBisectService } from 'vs/workbench/services/extensionManagement/browser/extensionBisect' +import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount' class NullLoggerService extends AbstractLoggerService { constructor () { @@ -436,6 +444,13 @@ registerSingleton(IProductService, class ProductService implements IProductServi serverApplicationName = 'code-server-oss' }, InstantiationType.Eager) +registerSingleton(IExtensionTipsService, class ExtensionTipsService implements IExtensionTipsService { + readonly _serviceBrand = undefined + getConfigBasedTips = async () => [] + getImportantExecutableBasedTips = async () => [] + getOtherExecutableBasedTips = async () => [] +}, InstantiationType.Eager) + registerSingleton(ILanguageStatusService, class LanguageStatusServiceImpl implements ILanguageStatusService { declare _serviceBrand: undefined @@ -940,6 +955,93 @@ registerSingleton(IExtensionsWorkbenchService, class ExtensionsWorkbenchService toggleExtensionIgnoredToSync = unsupported }, InstantiationType.Eager) +registerSingleton(IExtensionManagementServerService, class ExtensionManagementServerService implements IExtensionManagementServerService { + _serviceBrand = undefined + localExtensionManagementServer = null + remoteExtensionManagementServer = null + webExtensionManagementServer = null + + getExtensionManagementServer (_extension: IExtension) { + return null + } + + getExtensionInstallLocation (_extension: IExtension) { + return null + } +}, InstantiationType.Eager) + +registerSingleton(IExtensionRecommendationsService, class ExtensionRecommendationsService implements IExtensionRecommendationsService { + _serviceBrand: undefined + onDidChangeRecommendations = Event.None + getAllRecommendationsWithReason = () => ({}) + getImportantRecommendations = async () => [] + getOtherRecommendations = async () => [] + getFileBasedRecommendations = () => [] + getExeBasedRecommendations = async () => ({ important: [], others: [] }) + getConfigBasedRecommendations = async () => ({ important: [], others: [] }) + getWorkspaceRecommendations = async () => [] + getKeymapRecommendations = () => [] + getLanguageRecommendations = () => [] + getRemoteRecommendations = () => [] +}, InstantiationType.Eager) +registerSingleton(IUserDataAutoSyncService, class UserDataAutoSyncService implements IUserDataAutoSyncService { + _serviceBrand: undefined + readonly onError = Event.None + turnOn = unsupported + turnOff = unsupported + triggerSync = unsupported +}, InstantiationType.Eager) + +registerSingleton(IIgnoredExtensionsManagementService, class IgnoredExtensionsManagementService implements IIgnoredExtensionsManagementService { + _serviceBrand: undefined + getIgnoredExtensions = () => [] + hasToNeverSyncExtension = () => false + hasToAlwaysSyncExtension = () => false + updateIgnoredExtensions = unsupported + updateSynchronizedExtensions = unsupported +}, InstantiationType.Eager) + +registerSingleton(IExtensionRecommendationNotificationService, class ExtensionRecommendationNotificationService implements IExtensionRecommendationNotificationService { + _serviceBrand: undefined + readonly ignoredRecommendations: string[] = [] + hasToIgnoreRecommendationNotifications = () => false + promptImportantExtensionsInstallNotification = unsupported + promptWorkspaceRecommendations = unsupported +}, InstantiationType.Eager) + +registerSingleton(IWebExtensionsScannerService, class WebExtensionsScannerService implements IWebExtensionsScannerService { + _serviceBrand: undefined + scanSystemExtensions = async () => [] + scanUserExtensions = async () => [] + scanExtensionsUnderDevelopment = async () => [] + scanExistingExtension = async () => null + addExtension = unsupported + addExtensionFromGallery = unsupported + removeExtension = async () => {} + copyExtensions = async () => {} + updateMetadata = unsupported + scanExtensionManifest = async () => null +}, InstantiationType.Eager) + +registerSingleton(IExtensionIgnoredRecommendationsService, class ExtensionIgnoredRecommendationsService implements IExtensionIgnoredRecommendationsService { + _serviceBrand: undefined + onDidChangeIgnoredRecommendations = Event.None + ignoredRecommendations = [] + onDidChangeGlobalIgnoredRecommendation = Event.None + globalIgnoredRecommendations = [] + toggleGlobalIgnoredRecommendation = unsupported +}, InstantiationType.Eager) + +registerSingleton(IWorkspaceExtensionsConfigService, class WorkspaceExtensionsConfigService implements IWorkspaceExtensionsConfigService { + _serviceBrand: undefined + onDidChangeExtensionsConfigs = Event.None + getExtensionsConfigs = unsupported + getRecommendations = unsupported + getUnwantedRecommendations = unsupported + toggleRecommendation = unsupported + toggleUnwantedRecommendation = unsupported +}, InstantiationType.Eager) + registerSingleton(IWorkbenchExtensionEnablementService, class WorkbenchExtensionEnablementService implements IWorkbenchExtensionEnablementService { _serviceBrand: undefined onEnablementChanged = Event.None @@ -1071,6 +1173,13 @@ class SimpleExtensionResourceLoaderService extends AbstractExtensionResourceLoad } registerSingleton(IExtensionResourceLoaderService, SimpleExtensionResourceLoaderService, InstantiationType.Eager) +registerSingleton(IBuiltinExtensionsScannerService, class BuiltinExtensionsScannerService implements IBuiltinExtensionsScannerService { + _serviceBrand: undefined + scanBuiltinExtensions () { + return Promise.resolve([]) + } +}, InstantiationType.Eager) + registerSingleton(IHoverService, class HoverService implements IHoverService { showAndFocusLastHover = unsupported _serviceBrand: undefined @@ -1100,6 +1209,22 @@ registerSingleton(IExplorerService, class ExplorerService implements IExplorerSe registerSingleton(IExtensionStorageService, ExtensionStorageService, InstantiationType.Delayed) +registerSingleton(IGlobalExtensionEnablementService, class GlobalExtensionEnablementService implements IGlobalExtensionEnablementService { + _serviceBrand: undefined + onDidChangeEnablement = Event.None + getDisabledExtensions () { + return [] + } + + enableExtension () { + return Promise.resolve(true) + } + + disableExtension () { + return Promise.resolve(true) + } +}, InstantiationType.Delayed) + registerSingleton(ILanguagePackService, class LanguagePackService implements ILanguagePackService { _serviceBrand: undefined async getAvailableLanguages (): Promise { @@ -1666,6 +1791,17 @@ registerSingleton(IWebviewViewService, class WebviewService implements IWebviewV resolve = unsupported }, InstantiationType.Delayed) +registerSingleton(ILocaleService, class LocaleService implements ILocaleService { + _serviceBrand: undefined + setLocale (_languagePackItem: ILanguagePackItem, _skipDialog?: boolean) { + return Promise.resolve() + } + + clearLocalePreference () { + return Promise.resolve() + } +}, InstantiationType.Delayed) + registerSingleton(IWebviewWorkbenchService, class WebviewWorkbenchService implements IWebviewWorkbenchService { _serviceBrand: undefined get iconManager () { @@ -1904,6 +2040,39 @@ registerSingleton(IInteractiveDocumentService, class InteractiveDocumentService willRemoveInteractiveDocument = unsupported }, InstantiationType.Delayed) +registerSingleton(IActiveLanguagePackService, class ActiveLanguagePackService implements IActiveLanguagePackService { + readonly _serviceBrand: undefined + getExtensionIdProvidingCurrentLocale () { + return Promise.resolve(undefined) + } +}, InstantiationType.Eager) + +registerSingleton(IRemoteUserDataProfilesService, class RemoteUserDataProfilesService implements IRemoteUserDataProfilesService { + _serviceBrand: undefined + getRemoteProfiles = async () => [] + getRemoteProfile = unsupported +}, InstantiationType.Eager) + +registerSingleton(IExtensionBisectService, class ExtensionBisectService implements IExtensionBisectService { + _serviceBrand: undefined + isDisabledByBisect = () => false + isActive = false + disabledCount = 0 + start = unsupported + next = unsupported + reset = unsupported +}, InstantiationType.Eager) +registerSingleton(IUserDataSyncAccountService, class UserDataSyncAccountService implements IUserDataSyncAccountService { + _serviceBrand: undefined + + readonly onTokenFailed = Event.None + readonly account = undefined + readonly onDidChangeAccount = Event.None + updateAccount (): Promise { + return Promise.resolve() + } +}, InstantiationType.Eager) + registerSingleton(IInlineChatService, class InlineChatService implements IInlineChatService { onDidChangeProviders = Event.None _serviceBrand: undefined diff --git a/src/override/vs/base/common/semver/semver.ts b/src/override/vs/base/common/semver/semver.ts index 44de371f..7b17c1e3 100644 --- a/src/override/vs/base/common/semver/semver.ts +++ b/src/override/vs/base/common/semver/semver.ts @@ -1,5 +1 @@ -export const gte = (): boolean => false -export const gt = (): boolean => false -export const lt = (): boolean => false -export const lte = (): boolean => false -export const valid = (): boolean => false +export { gte, gt, lt, lte, valid, eq, rcompare } from 'semver' diff --git a/src/server/server-assets.ts b/src/server/server-assets.ts index d3b38630..86328c95 100644 --- a/src/server/server-assets.ts +++ b/src/server/server-assets.ts @@ -1,6 +1,7 @@ import { registerAssets } from '../assets' registerAssets({ + '': new URL('.', import.meta.url).toString(), 'vs/code/browser/workbench/workbench.html': new URL('vs/code/browser/workbench/workbench.html', import.meta.url).toString(), 'bootstrap-fork': new URL('bootstrap-fork.js', import.meta.url).toString() }) diff --git a/src/server/server-main.ts b/src/server/server-main.ts new file mode 100644 index 00000000..7952ad43 --- /dev/null +++ b/src/server/server-main.ts @@ -0,0 +1,127 @@ +import './server-assets' +import type { IServerAPI } from 'vs/server/node/remoteExtensionHostAgentServer' +import { createServer } from 'vs/server/node/server.main.js' +import { buildHelpMessage, buildVersionMessage, parseArgs } from 'vs/platform/environment/node/argv' +import { ServerParsedArgs, serverOptions } from 'vs/server/node/serverEnvironmentService' +import product from 'vs/platform/product/common/product' +import { AddressInfo, ListenOptions, Socket } from 'net' +import http from 'http' + +export async function start (options: ListenOptions): Promise { + let _remoteExtensionHostAgentServer: IServerAPI | null = null + let _remoteExtensionHostAgentServerPromise: Promise | null = null + const getRemoteExtensionHostAgentServer = (): Promise => { + if (_remoteExtensionHostAgentServerPromise == null) { + _remoteExtensionHostAgentServerPromise = createServer(address).then(server => { + _remoteExtensionHostAgentServer = server + return server + }) + } + return _remoteExtensionHostAgentServerPromise + } + + let address: AddressInfo | string | null = null + const server = http.createServer(async (req, res) => { + const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer() + return remoteExtensionHostAgentServer.handleRequest(req, res) + }) + server.on('upgrade', async (req, socket) => { + const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer() + return remoteExtensionHostAgentServer.handleUpgrade(req, socket) + }) + server.on('error', async (err) => { + const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer() + return remoteExtensionHostAgentServer.handleServerError(err) + }) + + server.listen(options, async () => { + address = server.address() + if (address === null) { + throw new Error('Unexpected server address') + } + + // eslint-disable-next-line no-console + console.log(`Server bound to ${typeof address === 'string' ? address : `${address.address}:${address.port} (${address.family})`}`) + + await getRemoteExtensionHostAgentServer() + }) + + process.on('exit', () => { + server.close() + if (_remoteExtensionHostAgentServer != null) { + _remoteExtensionHostAgentServer.dispose() + } + }) +} + +function parseRange (strRange: string) { + const match = strRange.match(/^(\d+)-(\d+)$/) + if (match != null) { + const start = parseInt(match[1]!, 10); const end = parseInt(match[2]!, 10) + if (start > 0 && start <= end && end <= 65535) { + return { start, end } + } + } + return undefined +} + +async function findFreePort (host: string, start: number, end: number) { + const testPort = (port: number) => { + return new Promise((resolve) => { + const server = http.createServer() + server.listen(port, host, () => { + server.close() + resolve(true) + }).on('error', () => { + resolve(false) + }) + }) + } + for (let port = start; port <= end; port++) { + if (await testPort(port)) { + return port + } + } + return undefined +} + +async function parsePort (host: string, strPort: string | undefined) { + if (strPort != null) { + let range + if (strPort.match(/^\d+$/) != null) { + return parseInt(strPort, 10) + } else if ((range = parseRange(strPort)) != null) { + const port = await findFreePort(host, range.start, range.end) + if (port !== undefined) { + return port + } + // Remote-SSH extension relies on this exact port error message, treat as an API + console.warn(`--port: Could not find free port in range: ${range.start} - ${range.end} (inclusive).`) + process.exit(1) + } else { + console.warn(`--port "${strPort}" is not a valid number or range. Ranges must be in the form 'from-to' with 'from' an integer larger than 0 and not larger than 'end'.`) + process.exit(1) + } + } + return 8000 +} + +const parsedArgs = parseArgs(process.argv.slice(2), serverOptions) +if (parsedArgs.help) { + const serverOptionsWithoutExtensionManagement = Object.fromEntries(Object.entries(serverOptions).filter(([, def]) => def.cat !== 'e')) + // eslint-disable-next-line no-console + console.log(buildHelpMessage(product.nameLong, 'vscode-ext-host-server', product.version, serverOptionsWithoutExtensionManagement, { noInputFiles: true, noPipe: true })) +} else if (parsedArgs.version) { + // eslint-disable-next-line no-console + console.log(buildVersionMessage(product.version, product.commit)) +} else { + const host = parsedArgs.host ?? 'localhost' + + const nodeListenOptions = ( + parsedArgs['socket-path'] != null + ? { path: parsedArgs['socket-path'] } + : { host, port: await parsePort(host, parsedArgs.port) } + ) + + void start(nodeListenOptions) +} diff --git a/src/server/server.ts b/src/server/server.ts index 7952ad43..021890a7 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -1,127 +1,19 @@ -import './server-assets' -import type { IServerAPI } from 'vs/server/node/remoteExtensionHostAgentServer' -import { createServer } from 'vs/server/node/server.main.js' -import { buildHelpMessage, buildVersionMessage, parseArgs } from 'vs/platform/environment/node/argv' -import { ServerParsedArgs, serverOptions } from 'vs/server/node/serverEnvironmentService' -import product from 'vs/platform/product/common/product' -import { AddressInfo, ListenOptions, Socket } from 'net' -import http from 'http' - -export async function start (options: ListenOptions): Promise { - let _remoteExtensionHostAgentServer: IServerAPI | null = null - let _remoteExtensionHostAgentServerPromise: Promise | null = null - const getRemoteExtensionHostAgentServer = (): Promise => { - if (_remoteExtensionHostAgentServerPromise == null) { - _remoteExtensionHostAgentServerPromise = createServer(address).then(server => { - _remoteExtensionHostAgentServer = server - return server - }) - } - return _remoteExtensionHostAgentServerPromise - } - - let address: AddressInfo | string | null = null - const server = http.createServer(async (req, res) => { - const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer() - return remoteExtensionHostAgentServer.handleRequest(req, res) - }) - server.on('upgrade', async (req, socket) => { - const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer() - return remoteExtensionHostAgentServer.handleUpgrade(req, socket) - }) - server.on('error', async (err) => { - const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer() - return remoteExtensionHostAgentServer.handleServerError(err) - }) - - server.listen(options, async () => { - address = server.address() - if (address === null) { - throw new Error('Unexpected server address') - } - - // eslint-disable-next-line no-console - console.log(`Server bound to ${typeof address === 'string' ? address : `${address.address}:${address.port} (${address.family})`}`) - - await getRemoteExtensionHostAgentServer() - }) - - process.on('exit', () => { - server.close() - if (_remoteExtensionHostAgentServer != null) { - _remoteExtensionHostAgentServer.dispose() - } - }) -} - -function parseRange (strRange: string) { - const match = strRange.match(/^(\d+)-(\d+)$/) - if (match != null) { - const start = parseInt(match[1]!, 10); const end = parseInt(match[2]!, 10) - if (start > 0 && start <= end && end <= 65535) { - return { start, end } - } +// Initialize the product information for the server, including the extension gallery URL. +// @ts-ignore +globalThis._VSCODE_PRODUCT_JSON = { + extensionsGallery: { + serviceUrl: 'https://open-vsx.org/vscode/gallery', + itemUrl: 'https://open-vsx.org/vscode/item', + resourceUrlTemplate: 'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}', + controlUrl: '', + recommendationsUrl: '', + nlsBaseUrl: '', + publisherUrl: '' } - return undefined } - -async function findFreePort (host: string, start: number, end: number) { - const testPort = (port: number) => { - return new Promise((resolve) => { - const server = http.createServer() - server.listen(port, host, () => { - server.close() - resolve(true) - }).on('error', () => { - resolve(false) - }) - }) - } - for (let port = start; port <= end; port++) { - if (await testPort(port)) { - return port - } - } - return undefined +// @ts-ignore +globalThis._VSCODE_PACKAGE_JSON = { + version: '1.83.0' } -async function parsePort (host: string, strPort: string | undefined) { - if (strPort != null) { - let range - if (strPort.match(/^\d+$/) != null) { - return parseInt(strPort, 10) - } else if ((range = parseRange(strPort)) != null) { - const port = await findFreePort(host, range.start, range.end) - if (port !== undefined) { - return port - } - // Remote-SSH extension relies on this exact port error message, treat as an API - console.warn(`--port: Could not find free port in range: ${range.start} - ${range.end} (inclusive).`) - process.exit(1) - } else { - console.warn(`--port "${strPort}" is not a valid number or range. Ranges must be in the form 'from-to' with 'from' an integer larger than 0 and not larger than 'end'.`) - process.exit(1) - } - } - return 8000 -} - -const parsedArgs = parseArgs(process.argv.slice(2), serverOptions) -if (parsedArgs.help) { - const serverOptionsWithoutExtensionManagement = Object.fromEntries(Object.entries(serverOptions).filter(([, def]) => def.cat !== 'e')) - // eslint-disable-next-line no-console - console.log(buildHelpMessage(product.nameLong, 'vscode-ext-host-server', product.version, serverOptionsWithoutExtensionManagement, { noInputFiles: true, noPipe: true })) -} else if (parsedArgs.version) { - // eslint-disable-next-line no-console - console.log(buildVersionMessage(product.version, product.commit)) -} else { - const host = parsedArgs.host ?? 'localhost' - - const nodeListenOptions = ( - parsedArgs['socket-path'] != null - ? { path: parsedArgs['socket-path'] } - : { host, port: await parsePort(host, parsedArgs.port) } - ) - - void start(nodeListenOptions) -} +import('./server-main') diff --git a/src/service-override/environment.ts b/src/service-override/environment.ts index e367a854..4e02425b 100644 --- a/src/service-override/environment.ts +++ b/src/service-override/environment.ts @@ -15,6 +15,20 @@ class InjectedBrowserWorkbenchEnvironmentService extends BrowserWorkbenchEnviron export default function getServiceOverride (options: IWorkbenchConstructionOptions = {}): IEditorOverrideServices { return { [IEnvironmentService.toString()]: new SyncDescriptor(InjectedBrowserWorkbenchEnvironmentService, [], true), + [IProductService.toString()]: { + version: VSCODE_VERSION, + commit: VSCODE_REF, + nameShort: 'Code - OSS Dev', + nameLong: 'Code - OSS Dev', + applicationName: 'code-oss', + dataFolderName: '.vscode-oss', + urlProtocol: 'code-oss', + reportIssueUrl: 'https://github.com/microsoft/vscode/issues/new', + licenseName: 'MIT', + licenseUrl: 'https://github.com/microsoft/vscode/blob/main/LICENSE.txt', + serverApplicationName: 'code-server-oss', + ...(options.productConfiguration ?? {}) + }, [IBrowserWorkbenchEnvironmentService.toString()]: new SyncDescriptor(InjectedBrowserWorkbenchEnvironmentService, [options], true) } } diff --git a/src/service-override/extensionGallery.ts b/src/service-override/extensionGallery.ts new file mode 100644 index 00000000..924a6b88 --- /dev/null +++ b/src/service-override/extensionGallery.ts @@ -0,0 +1,72 @@ +import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' +import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' +import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement' +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService' +import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService' +import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions' +import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService' +import { ILocaleService } from 'vs/workbench/services/localization/common/locale' +import { WebLocaleService } from 'vs/workbench/services/localization/browser/localeService' +import { IExtensionManagementServerService, IWebExtensionsScannerService, IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement' +import { ExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagementServerService' +import { IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations' +import { ExtensionRecommendationsService } from 'vs/workbench/contrib/extensions/browser/extensionRecommendationsService' +import { WebExtensionsScannerService } from 'vs/workbench/services/extensionManagement/browser/webExtensionsScannerService' +import { IExtensionRecommendationNotificationService } from 'vs/platform/extensionRecommendations/common/extensionRecommendations' +import { IIgnoredExtensionsManagementService, IgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions' +import { ExtensionManifestPropertiesService, IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService' +import { IBuiltinExtensionsScannerService } from 'vs/platform/extensions/common/extensions' +import { BuiltinExtensionsScannerService } from 'vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService' +import { ExtensionIgnoredRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService' +import { IWorkspaceExtensionsConfigService, WorkspaceExtensionsConfigService } from 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig' +import { IRemoteExtensionsScannerService } from 'vs/platform/remote/common/remoteExtensionsScanner' +import { RemoteExtensionsScannerService } from 'vs/workbench/services/remote/common/remoteExtensionsScanner' +import { ExtensionRecommendationNotificationService } from 'vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService' +import { ExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionTipsService' +import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService' +import { WebExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/webExtensionManagementService' +import 'vs/workbench/contrib/extensions/browser/extensions.contribution' +import 'vs/workbench/contrib/extensions/browser/extensions.web.contribution' +import 'vs/workbench/contrib/logs/common/logs.contribution' +import { IRemoteUserDataProfilesService, RemoteUserDataProfilesService } from 'vs/workbench/services/userDataProfile/common/remoteUserDataProfiles' +import { ExtensionEnablementService } from 'vs/workbench/services/extensionManagement/browser/extensionEnablementService' +import 'vs/workbench/services/extensionManagement/browser/extensionBisect' +import { changeUrlDomain } from './tools/url' +import { registerAssets } from '../assets' + +registerAssets({ + 'vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html': () => changeUrlDomain(new URL('../assets/webWorkerExtensionHostIframe.html', import.meta.url).href, undefined) +}) + +export interface ExtensionGalleryOptions { + /** + * Whether we should only allow for web extensions to be installed, this is generally + * true if there is no server part. + */ + webOnly: boolean +} + +export default function getServiceOverride (options: ExtensionGalleryOptions = { webOnly: false }): IEditorOverrideServices { + return { + [ILocaleService.toString()]: new SyncDescriptor(WebLocaleService, [], false), + [IExtensionGalleryService.toString()]: new SyncDescriptor(ExtensionGalleryService, [], true), + [IGlobalExtensionEnablementService.toString()]: new SyncDescriptor(GlobalExtensionEnablementService, [], true), + [IExtensionsWorkbenchService.toString()]: new SyncDescriptor(ExtensionsWorkbenchService, [], true), + [IExtensionManagementServerService.toString()]: new SyncDescriptor(ExtensionManagementServerService, [], true), + [IExtensionRecommendationsService.toString()]: new SyncDescriptor(ExtensionRecommendationsService, [], true), + [IExtensionRecommendationNotificationService.toString()]: new SyncDescriptor(ExtensionRecommendationNotificationService, [], true), + [IWebExtensionsScannerService.toString()]: new SyncDescriptor(WebExtensionsScannerService, [], true), + [IExtensionIgnoredRecommendationsService.toString()]: new SyncDescriptor(ExtensionIgnoredRecommendationsService, [], true), + [IIgnoredExtensionsManagementService.toString()]: new SyncDescriptor(IgnoredExtensionsManagementService, [], true), + [IExtensionManifestPropertiesService.toString()]: new SyncDescriptor(ExtensionManifestPropertiesService, [], true), + [IExtensionManagementService.toString()]: options.webOnly + ? new SyncDescriptor(WebExtensionManagementService, [], true) + : new SyncDescriptor(ExtensionManagementService, [], true), + [IBuiltinExtensionsScannerService.toString()]: new SyncDescriptor(BuiltinExtensionsScannerService, [], true), + [IWorkspaceExtensionsConfigService.toString()]: new SyncDescriptor(WorkspaceExtensionsConfigService, [], true), + [IRemoteExtensionsScannerService.toString()]: new SyncDescriptor(RemoteExtensionsScannerService, [], true), + [IExtensionTipsService.toString()]: new SyncDescriptor(ExtensionTipsService, [], true), + [IRemoteUserDataProfilesService.toString()]: new SyncDescriptor(RemoteUserDataProfilesService, [], true), + [IWorkbenchExtensionEnablementService.toString()]: new SyncDescriptor(ExtensionEnablementService, [], true) + } +}