Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f3d0a7e5a | ||
|
|
b1ad6ffcb9 | ||
|
|
9f6d18ea26 | ||
|
|
fe7db4900a | ||
|
|
84728f0b21 | ||
|
|
aaf2d91a21 | ||
|
|
47e9d43922 | ||
|
|
f26309a23c | ||
|
|
0f9a0e8fb3 | ||
|
|
4029c1ec8f | ||
|
|
bbe1b7fecb | ||
|
|
740a2d3aa3 | ||
|
|
92fca0dcc3 | ||
|
|
8b3d9b9e0a | ||
|
|
cdac5bff64 | ||
|
|
70be9fe541 | ||
|
|
729456b10d | ||
|
|
aff005e196 | ||
|
|
53dccbb5ca | ||
|
|
1b1440ffd2 | ||
|
|
c5c764d78f | ||
|
|
3a8fbeb4da | ||
|
|
bd34cd510f |
1
.github/workflows/release.yaml
vendored
@@ -73,6 +73,7 @@ jobs:
|
||||
|
||||
- name: Install cross-compiler and system dependencies
|
||||
run: |
|
||||
sed -i 's/deb\.debian\.org/archive.debian.org/g' /etc/apt/sources.list
|
||||
dpkg --add-architecture $TARGET_ARCH
|
||||
apt update && apt install -y --no-install-recommends \
|
||||
crossbuild-essential-$TARGET_ARCH \
|
||||
|
||||
2
.github/workflows/security.yaml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
uses: aquasecurity/trivy-action@6c175e9c4083a92bbca2f9724c8a5e33bc2d97a5
|
||||
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37
|
||||
with:
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
|
||||
2
.github/workflows/trivy-docker.yaml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Trivy vulnerability scanner in image mode
|
||||
uses: aquasecurity/trivy-action@6c175e9c4083a92bbca2f9724c8a5e33bc2d97a5
|
||||
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37
|
||||
with:
|
||||
image-ref: "docker.io/codercom/code-server:latest"
|
||||
ignore-unfixed: true
|
||||
|
||||
60
CHANGELOG.md
@@ -22,6 +22,66 @@ Code v99.99.999
|
||||
|
||||
## Unreleased
|
||||
|
||||
## [4.102.2](https://github.com/coder/code-server/releases/tag/v4.102.2) - 2025-07-24
|
||||
|
||||
Code v1.102.2
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.102.2.
|
||||
|
||||
## [4.102.1](https://github.com/coder/code-server/releases/tag/v4.102.1) - 2025-07-17
|
||||
|
||||
Code v1.102.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.102.1.
|
||||
|
||||
## [4.102.0](https://github.com/coder/code-server/releases/tag/v4.102.0) - 2025-07-16
|
||||
|
||||
Code v1.102.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.102.0.
|
||||
|
||||
### Added
|
||||
|
||||
- Custom strings can be configured using the `--i18n` flag set to a JSON
|
||||
file. This can be used for either translation (and can be used alongside
|
||||
`--locale`) or for customizing the strings. See
|
||||
[./src/node/i18n/locales/en.json](./src/node/i18n/locales/en.json) for the
|
||||
available keys.
|
||||
|
||||
## [4.101.2](https://github.com/coder/code-server/releases/tag/v4.101.2) - 2025-06-25
|
||||
|
||||
Code v1.101.2
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.101.2.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix web views not loading due to 401 when requesting the service worker.
|
||||
|
||||
## [4.101.1](https://github.com/coder/code-server/releases/tag/v4.101.1) - 2025-06-20
|
||||
|
||||
Code v1.101.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.101.1.
|
||||
|
||||
## [4.101.0](https://github.com/coder/code-server/releases/tag/v4.101.0) - 2025-06-20
|
||||
|
||||
Code v1.101.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.101.0.
|
||||
|
||||
## [4.100.3](https://github.com/coder/code-server/releases/tag/v4.100.3) - 2025-06-03
|
||||
|
||||
Code v1.100.3
|
||||
|
||||
@@ -16,7 +16,7 @@ main() {
|
||||
# Package managers may shim their own "node" wrapper into the PATH, so run
|
||||
# node and ask it for its true path.
|
||||
local node_path
|
||||
node_path="$(node <<< 'console.info(process.execPath)')"
|
||||
node_path="$(node -p process.execPath)"
|
||||
|
||||
mkdir -p "$RELEASE_PATH/bin"
|
||||
mkdir -p "$RELEASE_PATH/lib"
|
||||
|
||||
@@ -112,7 +112,9 @@ EOF
|
||||
# this because we have an NPM package that could be installed on any platform.
|
||||
# The correct platform dependencies and scripts will be installed as part of
|
||||
# the post-install during `npm install` or when building a standalone release.
|
||||
npm run gulp "vscode-reh-web-linux-x64${MINIFY:+-min}"
|
||||
node --max-old-space-size=16384 --optimize-for-size \
|
||||
./node_modules/gulp/bin/gulp.js \
|
||||
"vscode-reh-web-linux-x64${MINIFY:+-min}"
|
||||
|
||||
# Reset so if you develop after building you will not be stuck with the wrong
|
||||
# commit (the dev client will use `oss-dev` but the dev server will still use
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Generate icons from a single favicon.svg. favicon.svg should have no fill
|
||||
# colors set.
|
||||
main() {
|
||||
cd src/browser/media
|
||||
|
||||
# We need .ico for backwards compatibility.
|
||||
# The other two are the only icon sizes required by Chrome and
|
||||
# we use them for stuff like apple-touch-icon as well.
|
||||
# https://web.dev/add-manifest/
|
||||
# We need .ico for backwards compatibility. The other two are the only icon
|
||||
# sizes required by Chrome and we use them for stuff like apple-touch-icon as
|
||||
# well. https://web.dev/add-manifest/
|
||||
#
|
||||
# This should be enough and we can always add more if there are problems.
|
||||
|
||||
#
|
||||
# -quiet to avoid https://github.com/ImageMagick/ImageMagick/issues/884
|
||||
# -background defaults to white but we want it transparent.
|
||||
# -density somehow makes the image both sharper and smaller in file size.
|
||||
#
|
||||
# https://imagemagick.org/script/command-line-options.php#background
|
||||
convert -quiet -background transparent -resize 256x256 favicon.svg favicon.ico
|
||||
# We do not generate the pwa-icon from the favicon as they are slightly different
|
||||
# designs and sizes.
|
||||
# See favicon.afdesign and #2401 for details on the differences.
|
||||
convert -quiet -background transparent -resize 192x192 pwa-icon.png pwa-icon-192.png
|
||||
convert -quiet -background transparent -resize 512x512 pwa-icon.png pwa-icon-512.png
|
||||
convert -quiet -background transparent \
|
||||
-resize 256x256 -density 256x256 \
|
||||
favicon.svg favicon.ico
|
||||
|
||||
# We use -quiet above to avoid https://github.com/ImageMagick/ImageMagick/issues/884
|
||||
# Generate PWA icons. There should be enough padding to support masking.
|
||||
convert -quiet -border 60x60 -bordercolor white -background white \
|
||||
-resize 192x192 -density 192x192 \
|
||||
favicon.svg pwa-icon-maskable-192.png
|
||||
convert -quiet -border 160x160 -bordercolor white -background white \
|
||||
-resize 512x512 -density 512x512 \
|
||||
favicon.svg pwa-icon-maskable-512.png
|
||||
|
||||
# The following adds dark mode support for the favicon as favicon-dark-support.svg
|
||||
# There is no similar capability for pwas or .ico so we can only add support to the svg.
|
||||
favicon_dark_style="<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
* {
|
||||
fill: white;
|
||||
}
|
||||
}
|
||||
</style>"
|
||||
# See https://stackoverflow.com/a/22901380/4283659
|
||||
# This escapes all newlines so that sed will accept them.
|
||||
favicon_dark_style="$(printf "%s\n" "$favicon_dark_style" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g')"
|
||||
sed "$(
|
||||
cat -n << EOF
|
||||
s%<rect id="favicon"%$favicon_dark_style<rect id="favicon"%
|
||||
EOF
|
||||
)" favicon.svg > favicon-dark-support.svg
|
||||
# Generate non-maskable PWA icons.
|
||||
magick pwa-icon-maskable-192.png \
|
||||
\( +clone -threshold 101% -fill white -draw "roundRectangle 0,0 %[fx:int(w)],%[fx:int(h)] 50,50" \) \
|
||||
-channel-fx "| gray=>alpha" \
|
||||
pwa-icon-192.png
|
||||
magick pwa-icon-maskable-512.png \
|
||||
\( +clone -threshold 101% -fill white -draw "roundRectangle 0,0 %[fx:int(w)],%[fx:int(h)] 100,100" \) \
|
||||
-channel-fx "| gray=>alpha" \
|
||||
pwa-icon-512.png
|
||||
|
||||
# The following adds dark mode support for the favicon as
|
||||
# favicon-dark-support.svg There is no similar capability for pwas or .ico so
|
||||
# we can only add support to the svg.
|
||||
favicon_dark_style="<style>@media (prefers-color-scheme: dark) {* { fill: white; }}</style>"
|
||||
cp favicon.svg favicon-dark-support.svg
|
||||
sed "s%<path%$favicon_dark_style\n <path%" favicon.svg > favicon-dark-support.svg
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -15,9 +15,9 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 3.27.3
|
||||
version: 3.29.2
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
appVersion: 4.100.3
|
||||
appVersion: 4.102.2
|
||||
|
||||
@@ -6,7 +6,7 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: codercom/code-server
|
||||
tag: '4.100.3'
|
||||
tag: '4.102.2'
|
||||
pullPolicy: Always
|
||||
|
||||
# Specifies one or more secrets to be used when pulling images from a
|
||||
@@ -75,8 +75,9 @@ extraArgs: []
|
||||
extraVars: []
|
||||
# - name: DISABLE_TELEMETRY
|
||||
# value: "true"
|
||||
# if dind is desired:
|
||||
# - name: DOCKER_HOST
|
||||
# value: "tcp://localhost:2375"
|
||||
# value: "tcp://localhost:2376"
|
||||
|
||||
##
|
||||
## Init containers parameters:
|
||||
@@ -139,25 +140,39 @@ lifecycle:
|
||||
# - -c
|
||||
# - curl -s -L SOME_SCRIPT | bash
|
||||
|
||||
# for dind, the following may be helpful
|
||||
# postStart:
|
||||
# exec:
|
||||
# command:
|
||||
# - /bin/sh
|
||||
# - -c
|
||||
# - |
|
||||
# sudo apt-get update \
|
||||
# && sudo apt-get install -y docker.io
|
||||
|
||||
## Enable an Specify container in extraContainers.
|
||||
## This is meant to allow adding code-server dependencies, like docker-dind.
|
||||
extraContainers: |
|
||||
# If docker-dind is used, DOCKER_HOST env is mandatory to set in "extraVars"
|
||||
#- name: docker-dind
|
||||
# image: docker:19.03-dind
|
||||
# imagePullPolicy: IfNotPresent
|
||||
# resources:
|
||||
# requests:
|
||||
# cpu: 250m
|
||||
# memory: 256M
|
||||
# securityContext:
|
||||
# privileged: true
|
||||
# procMount: Default
|
||||
# env:
|
||||
# - name: DOCKER_TLS_CERTDIR
|
||||
# value: ""
|
||||
# - name: DOCKER_DRIVER
|
||||
# value: "overlay2"
|
||||
# - name: docker-dind
|
||||
# image: docker:28.3.2-dind
|
||||
# imagePullPolicy: IfNotPresent
|
||||
# resources:
|
||||
# requests:
|
||||
# cpu: 1
|
||||
# ephemeral-storage: "50Gi"
|
||||
# memory: 10Gi
|
||||
# securityContext:
|
||||
# privileged: true
|
||||
# procMount: Default
|
||||
# env:
|
||||
# - name: DOCKER_TLS_CERTDIR
|
||||
# value: "" # disable TLS setup
|
||||
# command:
|
||||
# - dockerd
|
||||
# - --host=unix:///var/run/docker.sock
|
||||
# - --host=tcp://0.0.0.0:2376
|
||||
|
||||
|
||||
extraInitContainers: |
|
||||
# - name: customization
|
||||
|
||||
@@ -383,6 +383,9 @@ mount into `/home/coder/myproject` from inside the `code-server` container. You
|
||||
need to make sure the Docker daemon's `/home/coder/myproject` is the same as the
|
||||
one mounted inside the `code-server` container, and the mount will work.
|
||||
|
||||
If you want Docker enabled when deploying on Kubernetes, look at the `values.yaml`
|
||||
file for the 3 fields: `extraVars`, `lifecycle.postStart`, and `extraContainers`.
|
||||
|
||||
## How do I disable telemetry?
|
||||
|
||||
Use the `--disable-telemetry` flag to disable telemetry.
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
- [Proxying to a Svelte app](#proxying-to-a-svelte-app)
|
||||
- [Prefixing `/absproxy/<port>` with a path](#prefixing-absproxyport-with-a-path)
|
||||
- [Preflight requests](#preflight-requests)
|
||||
- [Internationalization and customization](#internationalization-and-customization)
|
||||
- [Available keys and placeholders](#available-keys-and-placeholders)
|
||||
- [Legacy flag](#legacy-flag)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- prettier-ignore-end -->
|
||||
@@ -458,3 +461,52 @@ By default, if you have auth enabled, code-server will authenticate all proxied
|
||||
requests including preflight requests. This can cause issues because preflight
|
||||
requests do not typically include credentials. To allow all preflight requests
|
||||
through the proxy without authentication, use `--skip-auth-preflight`.
|
||||
|
||||
## Internationalization and customization
|
||||
|
||||
code-server allows you to provide a JSON file to configure certain strings. This
|
||||
can be used for both internationalization and customization.
|
||||
|
||||
Create a JSON file with your custom strings:
|
||||
|
||||
```json
|
||||
{
|
||||
"WELCOME": "Welcome to {{app}}",
|
||||
"LOGIN_TITLE": "{{app}} Access Portal",
|
||||
"LOGIN_BELOW": "Please log in to continue",
|
||||
"PASSWORD_PLACEHOLDER": "Enter Password"
|
||||
}
|
||||
```
|
||||
|
||||
Then reference the file:
|
||||
|
||||
```shell
|
||||
code-server --i18n /path/to/custom-strings.json
|
||||
```
|
||||
|
||||
Or this can be done in the config file:
|
||||
|
||||
```yaml
|
||||
i18n: /path/to/custom-strings.json
|
||||
```
|
||||
|
||||
You can combine this with the `--locale` flag to configure language support for
|
||||
both code-server and VS Code in cases where code-server has no support but VS
|
||||
Code does. If you are using this for internationalization, please consider
|
||||
sending us a pull request to contribute it to `src/node/i18n/locales`.
|
||||
|
||||
### Available keys and placeholders
|
||||
|
||||
Refer to [../src/node/i18n/locales/en.json](../src/node/i18n/locales/en.json)
|
||||
for a full list of the available keys for translations. Note that the only
|
||||
placeholders supported for each key are the ones used in the default string.
|
||||
|
||||
The `--app-name` flag controls the `{{app}}` placeholder in templates. If you
|
||||
want to change the name, you can either:
|
||||
|
||||
1. Set `--app-name` (potentially alongside `--i18n`)
|
||||
2. Use `--i18n` and hardcode the name in your strings
|
||||
|
||||
### Legacy flag
|
||||
|
||||
The `--welcome-text` flag is now deprecated. Use the `WELCOME` key instead.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
imagemagick
|
||||
nodejs
|
||||
python3
|
||||
pkg-config
|
||||
|
||||
35
package-lock.json
generated
@@ -18,7 +18,7 @@
|
||||
"express": "^5.0.1",
|
||||
"http-proxy": "^1.18.1",
|
||||
"httpolyglot": "^0.1.2",
|
||||
"i18next": "^23.5.1",
|
||||
"i18next": "^25.3.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"limiter": "^2.1.0",
|
||||
"pem": "^1.14.8",
|
||||
@@ -70,13 +70,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
},
|
||||
"version": "7.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
|
||||
"integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -3317,9 +3313,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/i18next": {
|
||||
"version": "23.16.4",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.4.tgz",
|
||||
"integrity": "sha512-9NIYBVy9cs4wIqzurf7nLXPyf3R78xYbxExVqHLK9od3038rjpyOEzW+XB130kZ1N4PZ9inTtJ471CRJ4Ituyg==",
|
||||
"version": "25.3.0",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.3.0.tgz",
|
||||
"integrity": "sha512-ZSQIiNGfqSG6yoLHaCvrkPp16UejHI8PCDxFYaNG/1qxtmqNmqEg4JlWKlxkrUmrin2sEjsy+Mjy1TRozBhOgw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -3335,7 +3331,15 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.23.2"
|
||||
"@babel/runtime": "^7.27.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
@@ -5025,11 +5029,6 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
|
||||
},
|
||||
"node_modules/regexp.prototype.flags": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
|
||||
@@ -6080,7 +6079,7 @@
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
"express": "^5.0.1",
|
||||
"http-proxy": "^1.18.1",
|
||||
"httpolyglot": "^0.1.2",
|
||||
"i18next": "^23.5.1",
|
||||
"i18next": "^25.3.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"limiter": "^2.1.0",
|
||||
"pem": "^1.14.8",
|
||||
|
||||
@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/network.ts
|
||||
@@ -220,7 +220,9 @@ class RemoteAuthoritiesImpl {
|
||||
@@ -223,7 +223,9 @@ class RemoteAuthoritiesImpl {
|
||||
return URI.from({
|
||||
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
|
||||
authority: `${host}:${port}`,
|
||||
@@ -253,7 +253,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
@@ -332,7 +332,8 @@ class LocalStorageURLCallbackProvider ex
|
||||
@@ -333,7 +333,8 @@ class LocalStorageURLCallbackProvider ex
|
||||
this.startListening();
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
}
|
||||
|
||||
private startListening(): void {
|
||||
@@ -579,17 +580,6 @@ class WorkspaceProvider implements IWork
|
||||
@@ -578,17 +579,6 @@ class WorkspaceProvider implements IWork
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
(function () {
|
||||
|
||||
// Find config by checking for DOM
|
||||
@@ -598,8 +588,8 @@ function readCookie(name: string): strin
|
||||
@@ -597,8 +587,8 @@ function readCookie(name: string): strin
|
||||
if (!configElement || !configElementAttribute) {
|
||||
throw new Error('Missing web configuration element');
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
@@ -122,6 +122,7 @@ export interface NativeParsedArgs {
|
||||
@@ -134,6 +134,7 @@ export interface NativeParsedArgs {
|
||||
'disable-chromium-sandbox'?: boolean;
|
||||
sandbox?: boolean;
|
||||
'enable-coi'?: boolean;
|
||||
@@ -90,7 +90,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/environment/node/argv.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
|
||||
@@ -91,6 +91,7 @@ export const OPTIONS: OptionDescriptions
|
||||
@@ -104,6 +104,7 @@ export const OPTIONS: OptionDescriptions
|
||||
'user-data-dir': { type: 'string', cat: 'o', args: 'dir', description: localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.") },
|
||||
'profile': { type: 'string', 'cat': 'o', args: 'profileName', description: localize('profileName', "Opens the provided folder or workspace with the given profile and associates the profile with the workspace. If the profile does not exist, a new empty one is created.") },
|
||||
'help': { type: 'boolean', cat: 'o', alias: 'h', description: localize('help', "Print usage.") },
|
||||
|
||||
@@ -18,9 +18,9 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
import { ProtocolConstants } from '../../base/parts/ipc/common/ipc.net.js';
|
||||
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
|
||||
import { ConfigurationService } from '../../platform/configuration/common/configurationService.js';
|
||||
@@ -255,6 +255,9 @@ export async function setupServerService
|
||||
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
|
||||
socketServer.registerChannel('extensions', channel);
|
||||
@@ -267,6 +267,9 @@ export async function setupServerService
|
||||
|
||||
socketServer.registerChannel('mcpManagement', new McpManagementChannel(mcpManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)));
|
||||
|
||||
+ const languagePackChannel = ProxyChannel.fromService<RemoteAgentConnectionContext>(accessor.get(ILanguagePackService), disposables);
|
||||
+ socketServer.registerChannel('languagePacks', languagePackChannel);
|
||||
@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentServ
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
|
||||
@@ -101,7 +101,7 @@ export abstract class AbstractNativeEnvi
|
||||
@@ -98,7 +98,7 @@ export abstract class AbstractNativeEnvi
|
||||
return URI.file(join(vscodePortable, 'argv.json'));
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -19,6 +19,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -21,6 +21,7 @@ export const serverOptions: OptionDescri
|
||||
'disable-file-downloads': { type: 'boolean' },
|
||||
'disable-file-uploads': { type: 'boolean' },
|
||||
'disable-getting-started-override': { type: 'boolean' },
|
||||
@@ -198,7 +198,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -107,6 +108,7 @@ export interface ServerParsedArgs {
|
||||
@@ -109,6 +110,7 @@ export interface ServerParsedArgs {
|
||||
'disable-file-downloads'?: boolean;
|
||||
'disable-file-uploads'?: boolean;
|
||||
'disable-getting-started-override'?: boolean,
|
||||
@@ -244,10 +244,10 @@ Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePack
|
||||
+ return this.languagePackService.getInstalledLanguages()
|
||||
}
|
||||
}
|
||||
Index: code-server/lib/vscode/src/vs/workbench/services/localization/electron-sandbox/localeService.ts
|
||||
Index: code-server/lib/vscode/src/vs/workbench/services/localization/electron-browser/localeService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/services/localization/electron-sandbox/localeService.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/services/localization/electron-sandbox/localeService.ts
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/services/localization/electron-browser/localeService.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/services/localization/electron-browser/localeService.ts
|
||||
@@ -51,7 +51,8 @@ class NativeLocaleService implements ILo
|
||||
@IProductService private readonly productService: IProductService
|
||||
) { }
|
||||
@@ -335,18 +335,6 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
|
||||
}
|
||||
|
||||
override async run(): Promise<any> {
|
||||
Index: code-server/lib/vscode/build/gulpfile.reh.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/build/gulpfile.reh.js
|
||||
+++ code-server/lib/vscode/build/gulpfile.reh.js
|
||||
@@ -58,6 +58,7 @@ const serverResourceIncludes = [
|
||||
|
||||
// NLS
|
||||
'out-build/nls.messages.json',
|
||||
+ 'out-build/nls.keys.json', // Required to generate translations.
|
||||
|
||||
// Process monitor
|
||||
'out-build/vs/base/node/cpuUsage.sh',
|
||||
Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
|
||||
@@ -356,7 +344,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
|
||||
import './services/lifecycle/browser/lifecycleService.js';
|
||||
import './services/clipboard/browser/clipboardService.js';
|
||||
-import './services/localization/browser/localeService.js';
|
||||
+import './services/localization/electron-sandbox/localeService.js';
|
||||
+import './services/localization/electron-browser/localeService.js';
|
||||
import './services/path/browser/pathService.js';
|
||||
import './services/themes/browser/browserHostColorSchemeService.js';
|
||||
import './services/encryption/browser/encryptionService.js';
|
||||
|
||||
@@ -90,7 +90,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -16,6 +16,8 @@ export const serverOptions: OptionDescri
|
||||
@@ -18,6 +18,8 @@ export const serverOptions: OptionDescri
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check': { type: 'boolean' },
|
||||
'auth': { type: 'string' },
|
||||
@@ -99,7 +99,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -101,6 +103,8 @@ export interface ServerParsedArgs {
|
||||
@@ -103,6 +105,8 @@ export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
'auth'?: string;
|
||||
@@ -129,8 +129,8 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js';
|
||||
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';
|
||||
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
|
||||
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
|
||||
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
|
||||
@@ -139,7 +139,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from '../../platform/workspace/common/workspace.js';
|
||||
import { IWorkbenchLayoutService, Parts, positionToString } from '../services/layout/browser/layoutService.js';
|
||||
import { getRemoteName } from '../../platform/remote/common/remoteHosts.js';
|
||||
@@ -70,7 +70,7 @@ export class WorkbenchContextKeysHandler
|
||||
@@ -71,7 +71,7 @@ export class WorkbenchContextKeysHandler
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@@ -148,9 +148,9 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@@ -197,6 +197,10 @@ export class WorkbenchContextKeysHandler
|
||||
this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService);
|
||||
this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));
|
||||
@@ -200,6 +200,10 @@ export class WorkbenchContextKeysHandler
|
||||
this.auxiliaryBarMaximizedContext = AuxiliaryBarMaximizedContext.bindTo(this.contextKeyService);
|
||||
this.auxiliaryBarMaximizedContext.set(this.layoutService.isAuxiliaryBarMaximized());
|
||||
|
||||
+ // code-server
|
||||
+ IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
|
||||
@@ -330,7 +330,7 @@ Index: code-server/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderS
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderServer.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderServer.ts
|
||||
@@ -92,6 +92,7 @@ export abstract class AbstractDiskFileSy
|
||||
@@ -99,6 +99,7 @@ export abstract class AbstractDiskFileSy
|
||||
|
||||
private async readFile(uriTransformer: IURITransformer, _resource: UriComponents, opts?: IFileAtomicReadOptions): Promise<VSBuffer> {
|
||||
const resource = this.transformIncoming(uriTransformer, _resource, true);
|
||||
@@ -338,7 +338,7 @@ Index: code-server/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderS
|
||||
const buffer = await this.provider.readFile(resource, opts);
|
||||
|
||||
return VSBuffer.wrap(buffer);
|
||||
@@ -110,6 +111,7 @@ export abstract class AbstractDiskFileSy
|
||||
@@ -117,6 +118,7 @@ export abstract class AbstractDiskFileSy
|
||||
}
|
||||
});
|
||||
|
||||
@@ -346,7 +346,7 @@ Index: code-server/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderS
|
||||
const fileStream = this.provider.readFileStream(resource, opts, cts.token);
|
||||
listenStream(fileStream, {
|
||||
onData: chunk => emitter.fire(VSBuffer.wrap(chunk)),
|
||||
@@ -130,7 +132,7 @@ export abstract class AbstractDiskFileSy
|
||||
@@ -137,7 +139,7 @@ export abstract class AbstractDiskFileSy
|
||||
|
||||
private writeFile(uriTransformer: IURITransformer, _resource: UriComponents, content: VSBuffer, opts: IFileWriteOptions): Promise<void> {
|
||||
const resource = this.transformIncoming(uriTransformer, _resource);
|
||||
|
||||
@@ -181,7 +181,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -18,6 +18,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -20,6 +20,7 @@ export const serverOptions: OptionDescri
|
||||
'auth': { type: 'string' },
|
||||
'disable-file-downloads': { type: 'boolean' },
|
||||
'disable-file-uploads': { type: 'boolean' },
|
||||
@@ -189,7 +189,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -105,6 +106,7 @@ export interface ServerParsedArgs {
|
||||
@@ -107,6 +108,7 @@ export interface ServerParsedArgs {
|
||||
'auth'?: string;
|
||||
'disable-file-downloads'?: boolean;
|
||||
'disable-file-uploads'?: boolean;
|
||||
@@ -217,12 +217,12 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js';
|
||||
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';
|
||||
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
|
||||
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
|
||||
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
|
||||
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
|
||||
@@ -200,6 +200,7 @@ export class WorkbenchContextKeysHandler
|
||||
@@ -203,6 +203,7 @@ export class WorkbenchContextKeysHandler
|
||||
// code-server
|
||||
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
|
||||
IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)
|
||||
|
||||
@@ -20,7 +20,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -15,6 +15,7 @@ import { URI } from '../../base/common/u
|
||||
@@ -17,6 +17,7 @@ import { join } from '../../base/common/
|
||||
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check': { type: 'boolean' },
|
||||
@@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -99,6 +100,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -101,6 +102,7 @@ export const serverOptions: OptionDescri
|
||||
export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
|
||||
@@ -96,7 +96,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
@@ -19,6 +19,7 @@ import { ISecretStorageProvider } from '
|
||||
@@ -20,6 +20,7 @@ import { ISecretStorageProvider } from '
|
||||
import { isFolderToOpen, isWorkspaceToOpen } from '../../../platform/window/common/window.js';
|
||||
import type { IWorkbenchConstructionOptions, IWorkspace, IWorkspaceProvider } from '../../../workbench/browser/web.api.js';
|
||||
import { AuthenticationSessionInfo } from '../../../workbench/services/authentication/browser/authenticationService.js';
|
||||
@@ -104,7 +104,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
import type { IURLCallbackProvider } from '../../../workbench/services/url/browser/urlService.js';
|
||||
import { create } from '../../../workbench/workbench.web.main.internal.js';
|
||||
|
||||
@@ -600,6 +601,39 @@ class WorkspaceProvider implements IWork
|
||||
@@ -599,6 +600,39 @@ class WorkspaceProvider implements IWork
|
||||
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
|
||||
workspaceProvider: WorkspaceProvider.create(config),
|
||||
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),
|
||||
|
||||
@@ -10,29 +10,29 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/build/gulpfile.reh.js
|
||||
+++ code-server/lib/vscode/build/gulpfile.reh.js
|
||||
@@ -256,8 +256,7 @@ function packageTask(type, platform, arc
|
||||
@@ -257,8 +257,7 @@ function packageTask(type, platform, arc
|
||||
|
||||
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
|
||||
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }))
|
||||
- .pipe(util.setExecutableBit(['**/*.sh']))
|
||||
- .pipe(filter(['**', '!**/*.js.map']));
|
||||
- .pipe(filter(['**', '!**/*.{js,css}.map']));
|
||||
+ .pipe(util.setExecutableBit(['**/*.sh']));
|
||||
|
||||
const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
|
||||
const isUIExtension = (manifest) => {
|
||||
@@ -296,9 +295,9 @@ function packageTask(type, platform, arc
|
||||
@@ -297,9 +296,9 @@ function packageTask(type, platform, arc
|
||||
.map(name => `.build/extensions/${name}/**`);
|
||||
|
||||
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
|
||||
- const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true });
|
||||
- const sources = es.merge(src, extensions, extensionsCommonDependencies)
|
||||
+ const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true })
|
||||
.pipe(filter(['**', '!**/*.js.map'], { dot: true }));
|
||||
.pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true }));
|
||||
+ const sources = es.merge(src, extensions, extensionsCommonDependencies);
|
||||
|
||||
let version = packageJson.version;
|
||||
const quality = product.quality;
|
||||
@@ -451,7 +450,7 @@ function tweakProductForServerWeb(produc
|
||||
@@ -452,7 +451,7 @@ function tweakProductForServerWeb(produc
|
||||
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
|
||||
bundleTask,
|
||||
util.rimraf(`out-vscode-${type}-min`),
|
||||
|
||||
@@ -25,7 +25,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.
|
||||
import { createApiFactoryAndRegisterActors } from '../common/extHost.api.impl.js';
|
||||
@@ -18,6 +19,7 @@ import { ExtensionRuntime } from '../com
|
||||
import { CLIServer } from './extHostCLIServer.js';
|
||||
import { realpathSync } from '../../../base/node/extpath.js';
|
||||
import { realpathSync } from '../../../base/node/pfs.js';
|
||||
import { ExtHostConsoleForwarder } from './extHostConsoleForwarder.js';
|
||||
+import { IExtHostWorkspace } from '../common/extHostWorkspace.js';
|
||||
import { ExtHostDiskFileSystemProvider } from './extHostDiskFileSystemProvider.js';
|
||||
@@ -96,7 +96,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
|
||||
import minimist from 'minimist';
|
||||
import * as nativeWatchdog from 'native-watchdog';
|
||||
import * as net from 'net';
|
||||
@@ -437,7 +438,28 @@ async function startExtensionHostProcess
|
||||
@@ -436,7 +437,28 @@ async function startExtensionHostProcess
|
||||
);
|
||||
|
||||
// rewrite onTerminate-function to be a proper shutdown
|
||||
|
||||
@@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
import { NullPolicyService } from '../../platform/policy/common/policy.js';
|
||||
import { OneDataSystemAppender } from '../../platform/telemetry/node/1dsAppender.js';
|
||||
import { LoggerService } from '../../platform/log/node/loggerService.js';
|
||||
@@ -158,11 +160,23 @@ export async function setupServerService
|
||||
@@ -163,11 +165,23 @@ export async function setupServerService
|
||||
const requestService = new RequestService('remote', configurationService, environmentService, logService);
|
||||
services.set(IRequestService, requestService);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -20,6 +20,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -22,6 +22,7 @@ export const serverOptions: OptionDescri
|
||||
'disable-file-uploads': { type: 'boolean' },
|
||||
'disable-getting-started-override': { type: 'boolean' },
|
||||
'locale': { type: 'string' },
|
||||
@@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -109,6 +110,7 @@ export interface ServerParsedArgs {
|
||||
@@ -111,6 +112,7 @@ export interface ServerParsedArgs {
|
||||
'disable-file-uploads'?: boolean;
|
||||
'disable-getting-started-override'?: boolean,
|
||||
'locale'?: string
|
||||
|
||||
@@ -117,8 +117,8 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -13,6 +13,8 @@ import { memoize } from '../../base/comm
|
||||
import { URI } from '../../base/common/uri.js';
|
||||
@@ -15,6 +15,8 @@ import { joinPath } from '../../base/com
|
||||
import { join } from '../../base/common/path.js';
|
||||
|
||||
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
|
||||
+ /* ----- code-server ----- */
|
||||
@@ -126,7 +126,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -95,6 +97,8 @@ export const serverOptions: OptionDescri
|
||||
@@ -97,6 +99,8 @@ export const serverOptions: OptionDescri
|
||||
};
|
||||
|
||||
export interface ServerParsedArgs {
|
||||
|
||||
@@ -71,10 +71,19 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
|
||||
|
||||
<meta http-equiv="Content-Security-Policy"
|
||||
- content="default-src 'none'; script-src 'sha256-gEAyFzmkyqMoTTnN+3KReFUYoHsK4RAJEb+6eiul+UY=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
+ content="default-src 'none'; script-src 'sha256-1qYtPnTQa4VwKNJO61EOhs2agF9TvuQSYIJ27OgzZqI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
+ content="default-src 'none'; script-src 'sha256-Oi71Tq4Buohx0KDH3yEbVJUzABnqYv9iVLo420HZXqI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
|
||||
<!-- Disable pinch zooming -->
|
||||
<meta name="viewport"
|
||||
@@ -238,7 +238,7 @@
|
||||
}
|
||||
|
||||
const swPath = encodeURI(`service-worker.js?v=${expectedWorkerVersion}&vscode-resource-base-authority=${searchParams.get('vscode-resource-base-authority')}&remoteAuthority=${searchParams.get('remoteAuthority') ?? ''}`);
|
||||
- navigator.serviceWorker.register(swPath, { type: 'module' })
|
||||
+ navigator.serviceWorker.register(swPath)
|
||||
.then(async registration => {
|
||||
/**
|
||||
* @param {MessageEvent} event
|
||||
@@ -351,6 +351,12 @@
|
||||
|
||||
const hostname = location.hostname;
|
||||
|
||||
BIN
src/browser/favicon.afdesign
LFS
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 2250 2250" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
* {
|
||||
fill: white;
|
||||
}
|
||||
}
|
||||
</style><rect id="favicon" x="0" y="0" width="2250" height="2250" style="fill:none;"/><g id="favicon1" serif:id="favicon"><path d="M1991.66,1034.72c-38.493,0 -64.144,-22.57 -64.144,-68.897l-0,-266.084c-0,-169.867 -69.982,-263.709 -250.762,-263.709l-83.976,0l-0,179.368l25.661,0c71.144,0 104.967,39.201 104.967,109.285l0,235.201c0,102.156 30.324,143.733 96.806,165.114c-66.482,20.196 -96.806,62.958 -96.806,165.114l0,174.621c0,48.7 0,96.216 -12.829,144.917c-12.829,45.141 -33.823,87.903 -62.98,124.726c-16.329,21.386 -34.991,39.202 -55.981,55.835l-0,23.755l83.971,-0c180.781,-0 250.763,-93.843 250.763,-263.709l-0,-266.084c-0,-47.516 24.485,-68.897 64.144,-68.897l47.822,-0l-0,-179.37l-46.656,-0l0,-1.186Z" style="fill-rule:nonzero;"/><path d="M1420.16,706.904l-258.923,0c-5.833,0 -10.495,-4.752 -10.495,-10.691l-0,-20.192c-0,-5.941 4.662,-10.692 10.495,-10.692l260.089,0c5.83,0 10.495,4.751 10.495,10.692l0,20.192c0,5.939 -5.833,10.691 -11.661,10.691Z" style="fill-rule:nonzero;"/><path d="M1464.48,963.474l-188.942,0c-5.833,0 -10.501,-4.754 -10.501,-10.693l0,-20.192c0,-5.938 4.668,-10.691 10.501,-10.691l188.942,-0c5.833,-0 10.495,4.753 10.495,10.691l-0,20.192c-0,4.754 -4.662,10.693 -10.495,10.693Z" style="fill-rule:nonzero;"/><path d="M1539.12,835.188l-377.885,0c-5.833,0 -10.495,-4.75 -10.495,-10.689l-0,-20.196c-0,-5.939 4.662,-10.69 10.495,-10.69l376.719,0c5.833,0 10.499,4.751 10.499,10.69l-0,20.196c-0,4.75 -3.5,10.689 -9.333,10.689Z" style="fill-rule:nonzero;"/><path d="M861.493,765.074c25.658,0 51.319,2.376 75.811,8.316l0,-48.705c0,-68.897 34.989,-109.285 104.971,-109.285l25.658,0l-0,-179.368l-83.977,0c-180.781,0 -250.758,93.842 -250.758,263.709l0,87.901c40.819,-14.252 83.977,-22.568 128.295,-22.568Z" style="fill-rule:nonzero;"/><path d="M1618.44,1411.25c-18.662,-150.861 -132.962,-276.776 -279.919,-305.285c-40.818,-8.314 -81.642,-9.504 -121.295,-2.376c-1.166,-0 -1.166,-1.189 -2.332,-1.189c-64.148,-136.605 -201.772,-226.884 -351.063,-226.884c-149.289,-0 -285.747,87.905 -351.062,224.51c-1.166,-0 -1.166,1.188 -2.332,1.188c-41.987,-4.753 -83.975,-2.379 -125.963,8.314c-144.623,35.634 -254.257,159.175 -274.085,308.847c-2.332,15.441 -3.499,30.883 -3.499,45.141c0,45.136 30.325,86.713 74.645,92.652c54.817,8.317 102.636,-34.448 101.469,-89.089c0,-8.317 0,-17.821 1.167,-26.134c9.331,-76.025 66.48,-140.168 141.123,-157.99c23.328,-5.939 46.654,-7.124 68.814,-3.559c71.146,9.502 141.124,-27.324 171.449,-91.467c22.162,-47.516 57.151,-89.094 103.804,-111.664c51.314,-24.946 109.633,-28.506 163.286,-9.499c55.979,20.192 97.966,62.954 123.627,116.409c26.824,52.27 39.653,89.093 96.805,96.221c23.325,3.559 88.639,2.374 113.132,1.185c47.82,0 95.64,16.631 129.463,51.079c22.156,23.757 38.485,53.455 45.486,86.715c10.495,53.455 -2.334,106.908 -33.825,147.296c-22.162,28.509 -52.485,49.89 -86.308,59.394c-16.329,4.754 -32.657,5.939 -48.986,5.939l-257.757,0c-51.314,0 -92.138,-41.573 -92.138,-93.842l0,-348.049c0,-14.251 -11.661,-26.13 -25.658,-26.13l-36.156,0c-71.148,1.185 -128.295,81.964 -128.295,167.488l-0,312.415c-0,92.652 73.476,167.488 164.451,167.488c0,0 404.714,-1.19 410.544,-1.19c93.304,-9.503 179.614,-58.204 237.927,-133.04c58.319,-72.46 85.142,-167.492 73.481,-264.894Z" style="fill-rule:nonzero;"/></g></svg>
|
||||
<svg width="100%" height="100%" viewBox="0 0 147 147" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>@media (prefers-color-scheme: dark) {* { fill: white; }}</style>
|
||||
<path d="m42.4214,39.655c-24.4057,0 -42.1554,13.1721 -42.1554,33.845c0,20.5814 18.4892,33.845 42.1554,33.845c23.6662,0 38.1803,-11.6171 38.7349,-28.7225l-21.0777,-0.4574c-0.9244,9.3303 -9.1059,15.1845 -17.6572,15.1845c-11.7406,0 -20.4306,-7.5922 -20.4306,-19.8496c0,-12.2574 8.69,-19.9868 20.4306,-20.2155c8.5513,-0.183 16.9177,5.9457 17.4723,15.276l21.0777,-0.6403c-0.4622,-16.8311 -14.1442,-28.2652 -38.55,-28.2652zm48.8446,2l55.468,0l0,64.0311l-55.468,0l0,-64.0311z" clip-rule="evenodd" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 685 B |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.3 KiB |
@@ -1 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 2250 2250" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="favicon" x="0" y="0" width="2250" height="2250" style="fill:none;"/><g id="favicon1" serif:id="favicon"><path d="M1991.66,1034.72c-38.493,0 -64.144,-22.57 -64.144,-68.897l-0,-266.084c-0,-169.867 -69.982,-263.709 -250.762,-263.709l-83.976,0l-0,179.368l25.661,0c71.144,0 104.967,39.201 104.967,109.285l0,235.201c0,102.156 30.324,143.733 96.806,165.114c-66.482,20.196 -96.806,62.958 -96.806,165.114l0,174.621c0,48.7 0,96.216 -12.829,144.917c-12.829,45.141 -33.823,87.903 -62.98,124.726c-16.329,21.386 -34.991,39.202 -55.981,55.835l-0,23.755l83.971,-0c180.781,-0 250.763,-93.843 250.763,-263.709l-0,-266.084c-0,-47.516 24.485,-68.897 64.144,-68.897l47.822,-0l-0,-179.37l-46.656,-0l0,-1.186Z" style="fill-rule:nonzero;"/><path d="M1420.16,706.904l-258.923,0c-5.833,0 -10.495,-4.752 -10.495,-10.691l-0,-20.192c-0,-5.941 4.662,-10.692 10.495,-10.692l260.089,0c5.83,0 10.495,4.751 10.495,10.692l0,20.192c0,5.939 -5.833,10.691 -11.661,10.691Z" style="fill-rule:nonzero;"/><path d="M1464.48,963.474l-188.942,0c-5.833,0 -10.501,-4.754 -10.501,-10.693l0,-20.192c0,-5.938 4.668,-10.691 10.501,-10.691l188.942,-0c5.833,-0 10.495,4.753 10.495,10.691l-0,20.192c-0,4.754 -4.662,10.693 -10.495,10.693Z" style="fill-rule:nonzero;"/><path d="M1539.12,835.188l-377.885,0c-5.833,0 -10.495,-4.75 -10.495,-10.689l-0,-20.196c-0,-5.939 4.662,-10.69 10.495,-10.69l376.719,0c5.833,0 10.499,4.751 10.499,10.69l-0,20.196c-0,4.75 -3.5,10.689 -9.333,10.689Z" style="fill-rule:nonzero;"/><path d="M861.493,765.074c25.658,0 51.319,2.376 75.811,8.316l0,-48.705c0,-68.897 34.989,-109.285 104.971,-109.285l25.658,0l-0,-179.368l-83.977,0c-180.781,0 -250.758,93.842 -250.758,263.709l0,87.901c40.819,-14.252 83.977,-22.568 128.295,-22.568Z" style="fill-rule:nonzero;"/><path d="M1618.44,1411.25c-18.662,-150.861 -132.962,-276.776 -279.919,-305.285c-40.818,-8.314 -81.642,-9.504 -121.295,-2.376c-1.166,-0 -1.166,-1.189 -2.332,-1.189c-64.148,-136.605 -201.772,-226.884 -351.063,-226.884c-149.289,-0 -285.747,87.905 -351.062,224.51c-1.166,-0 -1.166,1.188 -2.332,1.188c-41.987,-4.753 -83.975,-2.379 -125.963,8.314c-144.623,35.634 -254.257,159.175 -274.085,308.847c-2.332,15.441 -3.499,30.883 -3.499,45.141c0,45.136 30.325,86.713 74.645,92.652c54.817,8.317 102.636,-34.448 101.469,-89.089c0,-8.317 0,-17.821 1.167,-26.134c9.331,-76.025 66.48,-140.168 141.123,-157.99c23.328,-5.939 46.654,-7.124 68.814,-3.559c71.146,9.502 141.124,-27.324 171.449,-91.467c22.162,-47.516 57.151,-89.094 103.804,-111.664c51.314,-24.946 109.633,-28.506 163.286,-9.499c55.979,20.192 97.966,62.954 123.627,116.409c26.824,52.27 39.653,89.093 96.805,96.221c23.325,3.559 88.639,2.374 113.132,1.185c47.82,0 95.64,16.631 129.463,51.079c22.156,23.757 38.485,53.455 45.486,86.715c10.495,53.455 -2.334,106.908 -33.825,147.296c-22.162,28.509 -52.485,49.89 -86.308,59.394c-16.329,4.754 -32.657,5.939 -48.986,5.939l-257.757,0c-51.314,0 -92.138,-41.573 -92.138,-93.842l0,-348.049c0,-14.251 -11.661,-26.13 -25.658,-26.13l-36.156,0c-71.148,1.185 -128.295,81.964 -128.295,167.488l-0,312.415c-0,92.652 73.476,167.488 164.451,167.488c0,0 404.714,-1.19 410.544,-1.19c93.304,-9.503 179.614,-58.204 237.927,-133.04c58.319,-72.46 85.142,-167.492 73.481,-264.894Z" style="fill-rule:nonzero;"/></g></svg>
|
||||
<svg width="100%" height="100%" viewBox="0 0 147 147" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m42.4214,39.655c-24.4057,0 -42.1554,13.1721 -42.1554,33.845c0,20.5814 18.4892,33.845 42.1554,33.845c23.6662,0 38.1803,-11.6171 38.7349,-28.7225l-21.0777,-0.4574c-0.9244,9.3303 -9.1059,15.1845 -17.6572,15.1845c-11.7406,0 -20.4306,-7.5922 -20.4306,-19.8496c0,-12.2574 8.69,-19.9868 20.4306,-20.2155c8.5513,-0.183 16.9177,5.9457 17.4723,15.276l21.0777,-0.6403c-0.4622,-16.8311 -14.1442,-28.2652 -38.55,-28.2652zm48.8446,2l55.468,0l0,64.0311l-55.468,0l0,-64.0311z" clip-rule="evenodd" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 611 B |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 8.3 KiB |
BIN
src/browser/media/pwa-icon-maskable-192.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/browser/media/pwa-icon-maskable-512.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 19 KiB |
@@ -93,6 +93,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
|
||||
"app-name"?: string
|
||||
"welcome-text"?: string
|
||||
"abs-proxy-base-path"?: string
|
||||
i18n?: string
|
||||
/* Positional arguments. */
|
||||
_?: string[]
|
||||
}
|
||||
@@ -284,17 +285,24 @@ export const options: Options<Required<UserProvidedArgs>> = {
|
||||
"app-name": {
|
||||
type: "string",
|
||||
short: "an",
|
||||
description: "The name to use in branding. Will be shown in titlebar and welcome message",
|
||||
description:
|
||||
"Will replace the {{app}} placeholder in any strings, which by default includes the title bar and welcome message",
|
||||
},
|
||||
"welcome-text": {
|
||||
type: "string",
|
||||
short: "w",
|
||||
description: "Text to show on login page",
|
||||
deprecated: true,
|
||||
},
|
||||
"abs-proxy-base-path": {
|
||||
type: "string",
|
||||
description: "The base path to prefix to all absproxy requests",
|
||||
},
|
||||
i18n: {
|
||||
type: "string",
|
||||
path: true,
|
||||
description: "Path to JSON file with custom translations. Merges with default strings and supports all i18n keys.",
|
||||
},
|
||||
}
|
||||
|
||||
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { promises as fs } from "fs"
|
||||
import i18next, { init } from "i18next"
|
||||
import * as en from "./locales/en.json"
|
||||
import * as ja from "./locales/ja.json"
|
||||
@@ -5,29 +6,54 @@ import * as th from "./locales/th.json"
|
||||
import * as ur from "./locales/ur.json"
|
||||
import * as zhCn from "./locales/zh-cn.json"
|
||||
|
||||
const defaultResources = {
|
||||
en: {
|
||||
translation: en,
|
||||
},
|
||||
"zh-cn": {
|
||||
translation: zhCn,
|
||||
},
|
||||
th: {
|
||||
translation: th,
|
||||
},
|
||||
ja: {
|
||||
translation: ja,
|
||||
},
|
||||
ur: {
|
||||
translation: ur,
|
||||
},
|
||||
}
|
||||
|
||||
export async function loadCustomStrings(filePath: string): Promise<void> {
|
||||
try {
|
||||
// Read custom strings from file path only
|
||||
const fileContent = await fs.readFile(filePath, "utf8")
|
||||
const customStringsData = JSON.parse(fileContent)
|
||||
|
||||
// User-provided strings override all languages.
|
||||
Object.keys(defaultResources).forEach((locale) => {
|
||||
i18next.addResourceBundle(locale, "translation", customStringsData)
|
||||
})
|
||||
} catch (error) {
|
||||
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
||||
throw new Error(`Custom strings file not found: ${filePath}\nPlease ensure the file exists and is readable.`)
|
||||
} else if (error instanceof SyntaxError) {
|
||||
throw new Error(`Invalid JSON in custom strings file: ${filePath}\n${error.message}`)
|
||||
} else {
|
||||
throw new Error(
|
||||
`Failed to load custom strings from ${filePath}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init({
|
||||
lng: "en",
|
||||
fallbackLng: "en", // language to use if translations in user language are not available.
|
||||
returnNull: false,
|
||||
lowerCaseLng: true,
|
||||
debug: process.env.NODE_ENV === "development",
|
||||
resources: {
|
||||
en: {
|
||||
translation: en,
|
||||
},
|
||||
"zh-cn": {
|
||||
translation: zhCn,
|
||||
},
|
||||
th: {
|
||||
translation: th,
|
||||
},
|
||||
ja: {
|
||||
translation: ja,
|
||||
},
|
||||
ur: {
|
||||
translation: ur,
|
||||
},
|
||||
},
|
||||
resources: defaultResources,
|
||||
})
|
||||
|
||||
export default i18next
|
||||
|
||||
@@ -7,6 +7,7 @@ import { plural } from "../common/util"
|
||||
import { createApp, ensureAddress } from "./app"
|
||||
import { AuthType, DefaultedArgs, Feature, toCodeArgs, UserProvidedArgs } from "./cli"
|
||||
import { commit, version, vsRootPath } from "./constants"
|
||||
import { loadCustomStrings } from "./i18n"
|
||||
import { register } from "./routes"
|
||||
import { VSCodeModule } from "./routes/vscode"
|
||||
import { isDirectory, open } from "./util"
|
||||
@@ -122,6 +123,12 @@ export const runCodeServer = async (
|
||||
): Promise<{ dispose: Disposable["dispose"]; server: http.Server }> => {
|
||||
logger.info(`code-server ${version} ${commit}`)
|
||||
|
||||
// Load custom strings if provided
|
||||
if (args.i18n) {
|
||||
await loadCustomStrings(args.i18n)
|
||||
logger.info("Loaded custom strings")
|
||||
}
|
||||
|
||||
logger.info(`Using user-data-dir ${args["user-data-dir"]}`)
|
||||
logger.debug(`Using extensions-dir ${args["extensions-dir"]}`)
|
||||
|
||||
@@ -144,6 +151,8 @@ export const runCodeServer = async (
|
||||
logger.info(" - Using password from $PASSWORD")
|
||||
} else if (args.usingEnvHashedPassword) {
|
||||
logger.info(" - Using password from $HASHED_PASSWORD")
|
||||
} else if (args["hashed-password"]) {
|
||||
logger.info(` - Using hashed-password from ${args.config}`)
|
||||
} else {
|
||||
logger.info(` - Using password from ${args.config}`)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ const getRoot = async (req: Request, error?: Error): Promise<string> => {
|
||||
i18n.changeLanguage(locale)
|
||||
const appName = req.args["app-name"] || "code-server"
|
||||
const welcomeText = req.args["welcome-text"] || (i18n.t("WELCOME", { app: appName }) as string)
|
||||
|
||||
// Determine password message using i18n
|
||||
let passwordMsg = i18n.t("LOGIN_PASSWORD", { configFile: req.args.config })
|
||||
if (req.args.usingEnvPassword) {
|
||||
passwordMsg = i18n.t("LOGIN_USING_ENV_PASSWORD")
|
||||
|
||||
@@ -186,11 +186,22 @@ router.get("/manifest.json", async (req, res) => {
|
||||
display: "fullscreen",
|
||||
display_override: ["window-controls-overlay"],
|
||||
description: "Run Code on a remote server.",
|
||||
icons: [192, 512].map((size) => ({
|
||||
src: `{{BASE}}/_static/src/browser/media/pwa-icon-${size}.png`,
|
||||
type: "image/png",
|
||||
sizes: `${size}x${size}`,
|
||||
})),
|
||||
icons: [192, 512]
|
||||
.map((size) => [
|
||||
{
|
||||
src: `{{BASE}}/_static/src/browser/media/pwa-icon-${size}.png`,
|
||||
type: "image/png",
|
||||
sizes: `${size}x${size}`,
|
||||
purpose: "any",
|
||||
},
|
||||
{
|
||||
src: `{{BASE}}/_static/src/browser/media/pwa-icon-maskable-${size}.png`,
|
||||
type: "image/png",
|
||||
sizes: `${size}x${size}`,
|
||||
purpose: "maskable",
|
||||
},
|
||||
])
|
||||
.flat(),
|
||||
},
|
||||
null,
|
||||
2,
|
||||
|
||||
@@ -75,6 +75,7 @@ describe("parser", () => {
|
||||
"--verbose",
|
||||
["--app-name", "custom instance name"],
|
||||
["--welcome-text", "welcome to code"],
|
||||
["--i18n", "path/to/custom-strings.json"],
|
||||
"2",
|
||||
|
||||
["--locale", "ja"],
|
||||
@@ -145,6 +146,7 @@ describe("parser", () => {
|
||||
verbose: true,
|
||||
"app-name": "custom instance name",
|
||||
"welcome-text": "welcome to code",
|
||||
i18n: path.resolve("path/to/custom-strings.json"),
|
||||
version: true,
|
||||
"bind-addr": "192.169.0.1:8080",
|
||||
"session-socket": "/tmp/override-code-server-ipc-socket",
|
||||
@@ -347,6 +349,28 @@ describe("parser", () => {
|
||||
})
|
||||
})
|
||||
|
||||
it("should parse i18n flag with file path", async () => {
|
||||
// Test with file path (no validation at CLI parsing level)
|
||||
const args = parse(["--i18n", "/path/to/custom-strings.json"])
|
||||
expect(args).toEqual({
|
||||
i18n: "/path/to/custom-strings.json",
|
||||
})
|
||||
})
|
||||
|
||||
it("should parse i18n flag with relative file path", async () => {
|
||||
// Test with relative file path
|
||||
expect(() => parse(["--i18n", "./custom-strings.json"])).not.toThrow()
|
||||
expect(() => parse(["--i18n", "strings.json"])).not.toThrow()
|
||||
})
|
||||
|
||||
it("should support app-name and deprecated welcome-text flags", async () => {
|
||||
const args = parse(["--app-name", "My App", "--welcome-text", "Welcome!"])
|
||||
expect(args).toEqual({
|
||||
"app-name": "My App",
|
||||
"welcome-text": "Welcome!",
|
||||
})
|
||||
})
|
||||
|
||||
it("should use env var github token", async () => {
|
||||
process.env.GITHUB_TOKEN = "ga-foo"
|
||||
const args = parse([])
|
||||
|
||||
154
test/unit/node/i18n.test.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
import { promises as fs } from "fs"
|
||||
import * as os from "os"
|
||||
import * as path from "path"
|
||||
import { loadCustomStrings } from "../../../src/node/i18n"
|
||||
|
||||
describe("i18n", () => {
|
||||
let tempDir: string
|
||||
let validJsonFile: string
|
||||
let invalidJsonFile: string
|
||||
let nonExistentFile: string
|
||||
|
||||
beforeEach(async () => {
|
||||
// Create temporary directory for test files
|
||||
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "code-server-i18n-test-"))
|
||||
|
||||
// Create test files
|
||||
validJsonFile = path.join(tempDir, "valid.json")
|
||||
invalidJsonFile = path.join(tempDir, "invalid.json")
|
||||
nonExistentFile = path.join(tempDir, "does-not-exist.json")
|
||||
|
||||
// Write valid JSON file
|
||||
await fs.writeFile(
|
||||
validJsonFile,
|
||||
JSON.stringify({
|
||||
WELCOME: "Custom Welcome",
|
||||
LOGIN_TITLE: "My Custom App",
|
||||
LOGIN_BELOW: "Please log in to continue",
|
||||
}),
|
||||
)
|
||||
|
||||
// Write invalid JSON file
|
||||
await fs.writeFile(invalidJsonFile, '{"WELCOME": "Missing closing quote}')
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
// Clean up temporary directory
|
||||
await fs.rmdir(tempDir, { recursive: true })
|
||||
})
|
||||
|
||||
describe("loadCustomStrings", () => {
|
||||
it("should load valid JSON file successfully", async () => {
|
||||
// Should not throw an error
|
||||
await expect(loadCustomStrings(validJsonFile)).resolves.toBeUndefined()
|
||||
})
|
||||
|
||||
it("should throw clear error for non-existent file", async () => {
|
||||
await expect(loadCustomStrings(nonExistentFile)).rejects.toThrow(
|
||||
`Custom strings file not found: ${nonExistentFile}\nPlease ensure the file exists and is readable.`,
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw clear error for invalid JSON", async () => {
|
||||
await expect(loadCustomStrings(invalidJsonFile)).rejects.toThrow(
|
||||
`Invalid JSON in custom strings file: ${invalidJsonFile}`,
|
||||
)
|
||||
})
|
||||
|
||||
it("should handle empty JSON object", async () => {
|
||||
const emptyJsonFile = path.join(tempDir, "empty.json")
|
||||
await fs.writeFile(emptyJsonFile, "{}")
|
||||
|
||||
await expect(loadCustomStrings(emptyJsonFile)).resolves.toBeUndefined()
|
||||
})
|
||||
|
||||
it("should handle nested JSON objects", async () => {
|
||||
const nestedJsonFile = path.join(tempDir, "nested.json")
|
||||
await fs.writeFile(
|
||||
nestedJsonFile,
|
||||
JSON.stringify({
|
||||
WELCOME: "Hello World",
|
||||
NESTED: {
|
||||
KEY: "Value",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
await expect(loadCustomStrings(nestedJsonFile)).resolves.toBeUndefined()
|
||||
})
|
||||
|
||||
it("should handle special characters and unicode", async () => {
|
||||
const unicodeJsonFile = path.join(tempDir, "unicode.json")
|
||||
await fs.writeFile(
|
||||
unicodeJsonFile,
|
||||
JSON.stringify({
|
||||
WELCOME: "欢迎来到 code-server",
|
||||
LOGIN_TITLE: "Willkommen bei {{app}}",
|
||||
SPECIAL: "Special chars: àáâãäåæçèéêë 🚀 ♠️ ∆",
|
||||
}),
|
||||
"utf8",
|
||||
)
|
||||
|
||||
await expect(loadCustomStrings(unicodeJsonFile)).resolves.toBeUndefined()
|
||||
})
|
||||
|
||||
it("should handle generic errors that are not ENOENT or SyntaxError", async () => {
|
||||
const testFile = path.join(tempDir, "test.json")
|
||||
await fs.writeFile(testFile, "{}")
|
||||
|
||||
// Mock fs.readFile to throw a generic error
|
||||
const originalReadFile = fs.readFile
|
||||
const mockError = new Error("Permission denied")
|
||||
fs.readFile = jest.fn().mockRejectedValue(mockError)
|
||||
|
||||
await expect(loadCustomStrings(testFile)).rejects.toThrow(
|
||||
`Failed to load custom strings from ${testFile}: Permission denied`,
|
||||
)
|
||||
|
||||
// Restore original function
|
||||
fs.readFile = originalReadFile
|
||||
})
|
||||
|
||||
it("should handle errors that are not Error instances", async () => {
|
||||
const testFile = path.join(tempDir, "test.json")
|
||||
await fs.writeFile(testFile, "{}")
|
||||
|
||||
// Mock fs.readFile to throw a non-Error object
|
||||
const originalReadFile = fs.readFile
|
||||
fs.readFile = jest.fn().mockRejectedValue("String error")
|
||||
|
||||
await expect(loadCustomStrings(testFile)).rejects.toThrow(
|
||||
`Failed to load custom strings from ${testFile}: String error`,
|
||||
)
|
||||
|
||||
// Restore original function
|
||||
fs.readFile = originalReadFile
|
||||
})
|
||||
|
||||
it("should handle null/undefined errors", async () => {
|
||||
const testFile = path.join(tempDir, "test.json")
|
||||
await fs.writeFile(testFile, "{}")
|
||||
|
||||
// Mock fs.readFile to throw null
|
||||
const originalReadFile = fs.readFile
|
||||
fs.readFile = jest.fn().mockRejectedValue(null)
|
||||
|
||||
await expect(loadCustomStrings(testFile)).rejects.toThrow(`Failed to load custom strings from ${testFile}: null`)
|
||||
|
||||
// Restore original function
|
||||
fs.readFile = originalReadFile
|
||||
})
|
||||
|
||||
it("should complete without errors for valid input", async () => {
|
||||
const testFile = path.join(tempDir, "resource-test.json")
|
||||
const customStrings = {
|
||||
WELCOME: "Custom Welcome Message",
|
||||
LOGIN_TITLE: "Custom Login Title",
|
||||
}
|
||||
await fs.writeFile(testFile, JSON.stringify(customStrings))
|
||||
|
||||
// Should not throw any errors
|
||||
await expect(loadCustomStrings(testFile)).resolves.toBeUndefined()
|
||||
})
|
||||
})
|
||||
})
|
||||
175
test/unit/node/main.test.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import { setDefaults, parse } from "../../../src/node/cli"
|
||||
import { loadCustomStrings } from "../../../src/node/i18n"
|
||||
import { tmpdir } from "../../utils/helpers"
|
||||
|
||||
// Mock the i18n module
|
||||
jest.mock("../../../src/node/i18n", () => ({
|
||||
loadCustomStrings: jest.fn(),
|
||||
}))
|
||||
|
||||
// Mock logger to avoid console output during tests
|
||||
jest.mock("@coder/logger", () => ({
|
||||
logger: {
|
||||
info: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
level: 0,
|
||||
},
|
||||
field: jest.fn(),
|
||||
Level: {
|
||||
Trace: 0,
|
||||
Debug: 1,
|
||||
Info: 2,
|
||||
Warn: 3,
|
||||
Error: 4,
|
||||
},
|
||||
}))
|
||||
|
||||
const mockedLoadCustomStrings = loadCustomStrings as jest.MockedFunction<typeof loadCustomStrings>
|
||||
|
||||
describe("main", () => {
|
||||
let tempDir: string
|
||||
let mockServer: any
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await tmpdir("code-server-main-test")
|
||||
|
||||
// Reset mocks
|
||||
jest.clearAllMocks()
|
||||
|
||||
// Mock the server creation to avoid actually starting a server
|
||||
mockServer = {
|
||||
server: {
|
||||
listen: jest.fn(),
|
||||
address: jest.fn(() => ({ address: "127.0.0.1", port: 8080 })),
|
||||
close: jest.fn(),
|
||||
},
|
||||
editorSessionManagerServer: {
|
||||
address: jest.fn(() => null),
|
||||
},
|
||||
dispose: jest.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
// Clean up temp directory
|
||||
try {
|
||||
await fs.rmdir(tempDir, { recursive: true })
|
||||
} catch (error) {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
})
|
||||
|
||||
describe("runCodeServer", () => {
|
||||
it("should load custom strings when i18n flag is provided", async () => {
|
||||
// Create a test custom strings file
|
||||
const customStringsFile = path.join(tempDir, "custom-strings.json")
|
||||
await fs.writeFile(
|
||||
customStringsFile,
|
||||
JSON.stringify({
|
||||
WELCOME: "Custom Welcome",
|
||||
LOGIN_TITLE: "My App",
|
||||
}),
|
||||
)
|
||||
|
||||
// Create args with i18n flag
|
||||
const cliArgs = parse([
|
||||
`--config=${path.join(tempDir, "config.yaml")}`,
|
||||
`--user-data-dir=${tempDir}`,
|
||||
"--bind-addr=localhost:0",
|
||||
"--log=warn",
|
||||
"--auth=none",
|
||||
`--i18n=${customStringsFile}`,
|
||||
])
|
||||
const args = await setDefaults(cliArgs)
|
||||
|
||||
// Mock the app module
|
||||
jest.doMock("../../../src/node/app", () => ({
|
||||
createApp: jest.fn().mockResolvedValue(mockServer),
|
||||
ensureAddress: jest.fn().mockReturnValue(new URL("http://localhost:8080")),
|
||||
}))
|
||||
|
||||
// Mock routes module
|
||||
jest.doMock("../../../src/node/routes", () => ({
|
||||
register: jest.fn().mockResolvedValue(jest.fn()),
|
||||
}))
|
||||
|
||||
// Mock loadCustomStrings to succeed
|
||||
mockedLoadCustomStrings.mockResolvedValue(undefined)
|
||||
|
||||
// Import runCodeServer after mocking
|
||||
const mainModule = await import("../../../src/node/main")
|
||||
const result = await mainModule.runCodeServer(args)
|
||||
|
||||
// Verify that loadCustomStrings was called with the correct file path
|
||||
expect(mockedLoadCustomStrings).toHaveBeenCalledWith(customStringsFile)
|
||||
expect(mockedLoadCustomStrings).toHaveBeenCalledTimes(1)
|
||||
|
||||
// Clean up
|
||||
await result.dispose()
|
||||
})
|
||||
|
||||
it("should not load custom strings when i18n flag is not provided", async () => {
|
||||
// Create args without i18n flag
|
||||
const cliArgs = parse([
|
||||
`--config=${path.join(tempDir, "config.yaml")}`,
|
||||
`--user-data-dir=${tempDir}`,
|
||||
"--bind-addr=localhost:0",
|
||||
"--log=warn",
|
||||
"--auth=none",
|
||||
])
|
||||
const args = await setDefaults(cliArgs)
|
||||
|
||||
// Mock the app module
|
||||
jest.doMock("../../../src/node/app", () => ({
|
||||
createApp: jest.fn().mockResolvedValue(mockServer),
|
||||
ensureAddress: jest.fn().mockReturnValue(new URL("http://localhost:8080")),
|
||||
}))
|
||||
|
||||
// Mock routes module
|
||||
jest.doMock("../../../src/node/routes", () => ({
|
||||
register: jest.fn().mockResolvedValue(jest.fn()),
|
||||
}))
|
||||
|
||||
// Import runCodeServer after mocking
|
||||
const mainModule = await import("../../../src/node/main")
|
||||
const result = await mainModule.runCodeServer(args)
|
||||
|
||||
// Verify that loadCustomStrings was NOT called
|
||||
expect(mockedLoadCustomStrings).not.toHaveBeenCalled()
|
||||
|
||||
// Clean up
|
||||
await result.dispose()
|
||||
})
|
||||
|
||||
it("should handle errors when loadCustomStrings fails", async () => {
|
||||
// Create args with i18n flag pointing to non-existent file
|
||||
const nonExistentFile = path.join(tempDir, "does-not-exist.json")
|
||||
const cliArgs = parse([
|
||||
`--config=${path.join(tempDir, "config.yaml")}`,
|
||||
`--user-data-dir=${tempDir}`,
|
||||
"--bind-addr=localhost:0",
|
||||
"--log=warn",
|
||||
"--auth=none",
|
||||
`--i18n=${nonExistentFile}`,
|
||||
])
|
||||
const args = await setDefaults(cliArgs)
|
||||
|
||||
// Mock loadCustomStrings to throw an error
|
||||
const mockError = new Error("Custom strings file not found")
|
||||
mockedLoadCustomStrings.mockRejectedValue(mockError)
|
||||
|
||||
// Import runCodeServer after mocking
|
||||
const mainModule = await import("../../../src/node/main")
|
||||
|
||||
// Verify that runCodeServer throws the error from loadCustomStrings
|
||||
await expect(mainModule.runCodeServer(args)).rejects.toThrow("Custom strings file not found")
|
||||
|
||||
// Verify that loadCustomStrings was called
|
||||
expect(mockedLoadCustomStrings).toHaveBeenCalledWith(nonExistentFile)
|
||||
})
|
||||
})
|
||||
})
|
||||