Compare commits

...

55 Commits

Author SHA1 Message Date
Olivier Benz
ba774d989b Update Code to 1.104.0 (#7488) 2025-09-12 12:41:54 -08:00
Jinvien
1a7b770f5b Fix installing extensions from the Open VSX marketplace (#7479)
Open VSX uses a non-standard format for the `/latest` URL which must be added to the gallery config.
2025-09-11 14:26:49 -08:00
Anthony
626145cf66 Allow custom annotation to deployment (#7481) 2025-09-11 14:24:57 -08:00
Asher
b59a4f7366 Release v4.103.1 and v4.103.2 2025-08-28 11:55:58 -08:00
Olexandr88
54b33a75e0 Add Discord link to readme (#7465) 2025-08-25 10:32:11 -08:00
Olivier Benz
3c5deac16d Update Code to 1.103.2 (#7463) 2025-08-25 09:32:20 -08:00
Olivier Benz
fbaadbcfbc Update Code to 1.103.1 (#7459) 2025-08-15 12:31:17 -08:00
Asher
2bbb6e8cca Release v4.103.0 2025-08-12 14:31:17 -08:00
Olivier Benz
f1236d80b9 Update Code to 1.103.0 (#7458) 2025-08-08 17:10:23 -08:00
dependabot[bot]
b27d982c67 chore: bump prettier from 3.4.2 to 3.6.2 (#7407) 2025-08-04 12:46:32 -08:00
Asher
3f23840756 Remove import from express-serve-static-core
Mostly because express-serve-static-core is an implicit dependency.  We
could make it explicit, but the type we imported from it is just an
alias for qs.ParsedQs anyway.
2025-08-04 12:26:46 -08:00
Asher
e54467fb85 Run npm audit fix 2025-08-04 12:26:46 -08:00
Asher
8f738d29f2 Remove unused supertest dependency 2025-08-04 12:26:46 -08:00
Asher
5c0ff5013f Remove direct safe-buffer dependency
We do not use it directly.
2025-08-04 12:26:46 -08:00
dependabot[bot]
8a378df6e5 chore: bump eslint-import-resolver-typescript from 3.8.3 to 4.4.4 (#7404) 2025-08-04 11:37:04 -08:00
dependabot[bot]
a7e77ce4af chore: bump dawidd6/action-download-artifact from 10 to 11 (#7409)
Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 10 to 11.
- [Release notes](https://github.com/dawidd6/action-download-artifact/releases)
- [Commits](https://github.com/dawidd6/action-download-artifact/compare/v10...v11)

---
updated-dependencies:
- dependency-name: dawidd6/action-download-artifact
  dependency-version: '11'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 11:35:59 -08:00
dependabot[bot]
794def9a77 chore: bump on-headers and compression (#7427)
Bumps [on-headers](https://github.com/jshttp/on-headers) to 1.1.0 and updates ancestor dependency [compression](https://github.com/expressjs/compression). These dependencies need to be updated together.


Updates `on-headers` from 1.0.2 to 1.1.0
- [Release notes](https://github.com/jshttp/on-headers/releases)
- [Changelog](https://github.com/jshttp/on-headers/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/on-headers/compare/v1.0.2...v1.1.0)

Updates `compression` from 1.8.0 to 1.8.1
- [Release notes](https://github.com/expressjs/compression/releases)
- [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/compression/compare/1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: on-headers
  dependency-version: 1.1.0
  dependency-type: indirect
- dependency-name: compression
  dependency-version: 1.8.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 11:33:51 -08:00
Asher
b5a2ce2522 Use error handler in session server (#7455) 2025-08-04 11:05:48 -08:00
dependabot[bot]
bc15fa461c chore: bump form-data in /test (#7430)
---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 10:31:50 -08:00
dependabot[bot]
1805daed07 chore: bump aquasecurity/trivy-action from 0.31.0 to 0.32.0 (#7450)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.31.0 to 0.32.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](76071ef0d7...dc5a429b52)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 10:31:21 -08:00
Olivier Benz
6f3d0a7e5a Update Code to 1.102.3 (#7444) 2025-07-30 11:28:34 -08:00
Asher
b1ad6ffcb9 Release v4.102.2 2025-07-24 14:08:12 -08:00
Olivier Benz
9f6d18ea26 Update Code to 1.102.2 (#7436) 2025-07-24 12:07:27 -08:00
Sheldon Tsen
fe7db4900a Update values.yaml to better support dind (#7431) 2025-07-22 09:17:44 -08:00
Asher
84728f0b21 Release v4.102.1 2025-07-17 13:25:16 -08:00
Asher
aaf2d91a21 Deleted unused and outdated afdesign file 2025-07-17 13:25:15 -08:00
Olivier Benz
47e9d43922 Update Code to 1.102.1 (#7424) 2025-07-17 10:55:37 -08:00
Asher
f26309a23c Release v4.102.0 2025-07-16 18:56:42 -08:00
Asher
0f9a0e8fb3 Revert escaping for i18n strings
Looks like the library already escapes, so we were getting double
escaping.
2025-07-16 18:10:11 -08:00
Asher
4029c1ec8f Use Debian archives
Looks like buster has reached the end of its life, but updating to
bullseye would increase the glibc version.
2025-07-15 15:03:43 -08:00
dependabot[bot]
bbe1b7fecb chore: bump i18next from 23.16.4 to 25.3.0 (#7406)
Bumps [i18next](https://github.com/i18next/i18next) from 23.16.4 to 25.3.0.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v23.16.4...v25.3.0)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 25.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-15 12:40:04 -08:00
dependabot[bot]
740a2d3aa3 chore: bump aquasecurity/trivy-action from 0.30.0 to 0.31.0 (#7408)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.30.0 to 0.31.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](6c175e9c40...76071ef0d7)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-version: 0.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-15 12:39:08 -08:00
Alex Strick van Linschoten
92fca0dcc3 Add language customization flag (#7374)
This allows you to customize any string (that has a translation) or add your own translations.
2025-07-15 12:38:27 -08:00
Frank Lemanschik
8b3d9b9e0a Use native node -p to get exec path (#7420) 2025-07-15 12:08:37 -08:00
Olivier Benz
cdac5bff64 Update Code to 1.102.0 (#7418)
* Update Code to 1.102.0
* Increase maximum memory for building
2025-07-15 12:04:46 -08:00
Asher
70be9fe541 Add non-maskable PWA icons
It seems Chromium cannot use maskable icons.  It complains that the
"purpose" must contain "any", however maskable icons are not suitable
for the "any" purpose.

So, add pre-masked icons to be used for the "any" purpose.
2025-07-07 14:40:01 -08:00
Asher
729456b10d Release v4.101.2 2025-07-07 14:20:38 -08:00
Asher
aff005e196 Update Code to 1.101.2 2025-06-25 11:43:13 -08:00
Asher
53dccbb5ca Report if using hashed-password from config 2025-06-25 11:20:25 -08:00
Asher
1b1440ffd2 Update logo 2025-06-25 10:32:43 -08:00
Asher
c5c764d78f Do not use module type for service worker
It seems that this causes browser to not send cookies, which can result
in a 401.

Fixes #7389.
2025-06-25 10:32:35 -08:00
Asher
3a8fbeb4da Release v4.101.0 and v4.101.1 2025-06-25 10:32:09 -08:00
Olivier Benz
bd34cd510f Update Code to 1.101.1 (#7383) 2025-06-20 16:08:36 -08:00
Asher
27a112c3a7 Upgrade brace-expansion sub-dependency
Courtesy of `npm audit fix`.
2025-06-16 17:00:51 -08:00
dependabot[bot]
74cc50d5e6 chore: bump qs from 6.13.0 to 6.14.0 (#7363)
Bumps [qs](https://github.com/ljharb/qs) from 6.13.0 to 6.14.0.
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.13.0...v6.14.0)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 15:32:23 -08:00
dependabot[bot]
85ee441006 chore: bump typescript from 5.6.2 to 5.8.3 (#7335)
* chore: bump typescript from 5.6.2 to 5.8.3

Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.6.2 to 5.8.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.8.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.8.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* as T

* Update JSON error

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Asher <ash@coder.com>
2025-06-16 15:32:00 -08:00
dependabot[bot]
a56769b2c3 chore: bump heyhusen/archlinux-package-action from 2.2.1 to 2.4.0 (#7362)
Bumps [heyhusen/archlinux-package-action](https://github.com/heyhusen/archlinux-package-action) from 2.2.1 to 2.4.0.
- [Release notes](https://github.com/heyhusen/archlinux-package-action/releases)
- [Changelog](https://github.com/heyhusen/archlinux-package-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/heyhusen/archlinux-package-action/compare/v2.2.1...v2.4.0)

---
updated-dependencies:
- dependency-name: heyhusen/archlinux-package-action
  dependency-version: 2.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 13:07:03 -08:00
dependabot[bot]
05d8904ec5 chore: bump dawidd6/action-download-artifact from 9 to 10 (#7361)
Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 9 to 10.
- [Release notes](https://github.com/dawidd6/action-download-artifact/releases)
- [Commits](https://github.com/dawidd6/action-download-artifact/compare/v9...v10)

---
updated-dependencies:
- dependency-name: dawidd6/action-download-artifact
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 13:06:23 -08:00
dependabot[bot]
3669c96c9c chore: bump @types/compression from 1.7.5 to 1.8.0 (#7364)
Bumps [@types/compression](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/compression) from 1.7.5 to 1.8.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/compression)

---
updated-dependencies:
- dependency-name: "@types/compression"
  dependency-version: 1.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 13:05:03 -08:00
dependabot[bot]
37357b0142 chore: bump typescript-eslint from 8.29.0 to 8.33.0 (#7365)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.29.0 to 8.33.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.33.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.33.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 13:04:33 -08:00
Olivier Benz
405eb0f511 Update Code to 1.101.0 (#7376) 2025-06-16 13:03:47 -08:00
Jakub Domeracki
6e26dad1b1 fix: update GitHub Actions Runner images (#7379) 2025-06-16 12:04:57 -08:00
Asher
1671bf1c18 Release v4.100.3 2025-06-03 13:10:14 -08:00
Asher
1face85ad9 Sort some imports 2025-06-03 13:10:13 -08:00
Asher
9ec786b62a Ask not to put "latest" in bug report
Maybe this will help...
2025-06-03 13:10:11 -08:00
72 changed files with 1648 additions and 862 deletions

View File

@@ -20,6 +20,8 @@ body:
- **Remote OS**: Ubuntu
- **Remote Architecture**: amd64
- **`code-server --version`**: 4.0.1
Please do not just put "latest" for the version.
value: |
- Web Browser:
- Local OS:

View File

@@ -124,7 +124,7 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Validate package
uses: heyhusen/archlinux-package-action@v2.2.1
uses: heyhusen/archlinux-package-action@v2.4.0
env:
VERSION: ${{ env.VERSION }}
with:

View File

@@ -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 \
@@ -268,7 +269,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Download artifacts
uses: dawidd6/action-download-artifact@v9
uses: dawidd6/action-download-artifact@v11
id: download
with:
branch: ${{ github.ref }}

View File

@@ -43,7 +43,7 @@ jobs:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@v4
@@ -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@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4
with:
scan-type: "fs"
scan-ref: "."
@@ -72,7 +72,7 @@ jobs:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/autobuild to send a status report
name: Analyze with CodeQL
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout repository

View File

@@ -44,14 +44,14 @@ concurrency:
jobs:
trivy-scan-image:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner in image mode
uses: aquasecurity/trivy-action@6c175e9c4083a92bbca2f9724c8a5e33bc2d97a5
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4
with:
image-ref: "docker.io/codercom/code-server:latest"
ignore-unfixed: true

View File

@@ -1 +1 @@
20.19.0
22.18.0

View File

@@ -22,6 +22,98 @@ Code v99.99.999
## Unreleased
## [4.103.2](https://github.com/coder/code-server/releases/tag/v4.103.2) - 2025-08-25
Code v1.103.2
### Changed
- Update to Code 1.103.2.
## [4.103.1](https://github.com/coder/code-server/releases/tag/v4.103.1) - 2025-08-15
Code v1.103.1
### Changed
- Update to Code 1.103.1.
## [4.103.0](https://github.com/coder/code-server/releases/tag/v4.103.0) - 2025-08-12
Code v1.103.0
### Changed
- Update to Code 1.103.0.
## [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
### Changed
- Update to Code 1.100.3.
## [4.100.2](https://github.com/coder/code-server/releases/tag/v4.100.2) - 2025-05-15
Code v1.100.2
@@ -742,7 +834,6 @@ Code v1.68.1
would be accessible at `my.domain/proxy/8000/` without any authentication.
If all of the following apply to you please update as soon as possible:
- You run code-server with the built-in password authentication.
- You run unprotected HTTP services on ports accessible by code-server.

View File

@@ -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"

View File

@@ -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

View File

@@ -76,8 +76,8 @@ main() {
echo "USE AT YOUR OWN RISK!"
fi
if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-20}" ]; then
echo "ERROR: code-server currently requires node v20."
if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-22}" ]; then
echo "ERROR: code-server currently requires node v22."
if [ -n "$FORCE_NODE_VERSION" ]; then
echo "However, you have overrided the version check to use v$FORCE_NODE_VERSION."
fi

View File

@@ -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 "$@"

View File

@@ -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.2
version: 3.30.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.2
appVersion: 4.103.2

View File

@@ -7,6 +7,9 @@ metadata:
helm.sh/chart: {{ include "code-server.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.annotations }}
annotations: {{- toYaml .Values.annotations | nindent 4 }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount | default 1 }}
strategy:

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image:
repository: codercom/code-server
tag: '4.100.2'
tag: '4.103.2'
pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a
@@ -31,6 +31,9 @@ serviceAccount:
# If not set and create is true, a name is generated using the fullname template
name: ""
# Specifies annotations for deployment
annotations: {}
podAnnotations: {}
podSecurityContext: {}
@@ -75,8 +78,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 +143,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

View File

@@ -32,7 +32,7 @@ The prerequisites for contributing to code-server are almost the same as those
for [VS Code](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites).
Here is what is needed:
- `node` v20.x
- `node` v22.x
- `git` v2.x or greater
- [`git-lfs`](https://git-lfs.github.com)
- [`npm`](https://www.npmjs.com/)

View File

@@ -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.

View File

@@ -1,6 +1,6 @@
# code-server
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/coder/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://coder.com/community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/coder/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/coder/code-server) [![See latest](https://img.shields.io/static/v1?label=Docs&message=see%20latest&color=blue)](https://coder.com/docs/code-server/latest)
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/coder/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://coder.com/community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![Discord](https://img.shields.io/discord/747933592273027093)](https://discord.com/invite/coder) [![codecov](https://codecov.io/gh/coder/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/coder/code-server) [![See latest](https://img.shields.io/static/v1?label=Docs&message=see%20latest&color=blue)](https://coder.com/docs/code-server/latest)
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and
access it in the browser.

View File

@@ -11,7 +11,7 @@ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
```
6. Exit the terminal using `exit` and then reopen the terminal
7. Install and use Node.js 20:
7. Install and use Node.js 22:
```shell
nvm install 18

View File

@@ -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.

View File

@@ -82,13 +82,11 @@ _exact_ same commands presented in the rest of this document.
- For Arch Linux, code-server will install the AUR package.
- For any unrecognized Linux operating system, code-server will install the
latest standalone release into `~/.local`.
- Ensure that you add `~/.local/bin` to your `$PATH` to run code-server.
- For macOS, code-server will install the Homebrew package (if you don't have
Homebrew installed, code-server will install the latest standalone release
into `~/.local`).
- Ensure that you add `~/.local/bin` to your `$PATH` to run code-server.
- For FreeBSD, code-server will install the [npm package](#npm) with `npm`

View File

@@ -30,7 +30,7 @@ includes installing instructions based on your operating system.
## Node.js version
We use the same major version of Node.js shipped with Code's remote, which is
currently `20.x`. VS Code also [lists Node.js
currently `22.x`. VS Code also [lists Node.js
requirements](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites).
Using other versions of Node.js [may lead to unexpected
@@ -78,7 +78,7 @@ Proceed to [installing](#installing)
## FreeBSD
```sh
pkg install -y git python npm-node20 pkgconf
pkg install -y git python npm-node22 pkgconf
pkg install -y libinotify
```

View File

@@ -57,7 +57,7 @@ npm config set python python3
node -v
```
you will get Node version `v20`
you will get Node version `v22`
5. Now install code-server following our guide on [installing with npm](./npm.md)

View File

@@ -10,10 +10,11 @@
flake-utils.lib.eachDefaultSystem
(system:
let pkgs = nixpkgs.legacyPackages.${system};
nodejs = pkgs.nodejs_20;
nodejs = pkgs.nodejs_22;
in {
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [
imagemagick
nodejs
python3
pkg-config

936
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,7 @@
"@types/express": "^5.0.0",
"@types/http-proxy": "1.17.7",
"@types/js-yaml": "^4.0.6",
"@types/node": "20.x",
"@types/node": "22.x",
"@types/pem": "^1.14.1",
"@types/proxy-from-env": "^1.0.1",
"@types/safe-compare": "^1.1.0",
@@ -57,11 +57,11 @@
"doctoc": "^2.2.1",
"eslint": "^9.12.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-typescript": "^3.6.0",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-prettier": "^5.0.0",
"globals": "^16.1.0",
"prettier": "3.4.2",
"prettier": "3.6.2",
"prettier-plugin-sh": "^0.14.0",
"ts-node": "^10.9.1",
"typescript": "^5.6.2",
@@ -76,21 +76,20 @@
"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",
"proxy-agent": "^6.3.1",
"qs": "6.13.0",
"qs": "6.14.0",
"rotating-file-stream": "^3.1.1",
"safe-buffer": "^5.2.1",
"safe-compare": "^1.1.4",
"semver": "^7.5.4",
"ws": "^8.14.2",
"xdg-basedir": "^4.0.0"
},
"resolutions": {
"@types/node": "20.x"
"@types/node": "22.x"
},
"bin": {
"code-server": "out/node/entry.js"
@@ -105,7 +104,7 @@
"remote-development"
],
"engines": {
"node": "20"
"node": "22"
},
"jest": {
"transform": {

View File

@@ -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 {
@@ -232,7 +232,9 @@ class RemoteAuthoritiesImpl {
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,
@@ -111,7 +111,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -246,7 +246,9 @@ export class WebClientServer {
@@ -245,7 +245,9 @@ export class WebClientServer {
};
// Prefix routes with basePath for clients
@@ -122,7 +122,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
const queryConnectionToken = parsedUrl.query[connectionTokenQueryName];
if (typeof queryConnectionToken === 'string') {
@@ -285,10 +287,14 @@ export class WebClientServer {
@@ -284,10 +286,14 @@ export class WebClientServer {
};
const useTestResolver = (!this._environmentService.isBuilt && this._environmentService.args['use-test-resolver']);
@@ -138,7 +138,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
);
if (!remoteAuthority) {
return serveError(req, res, 400, `Bad request.`);
@@ -335,6 +341,7 @@ export class WebClientServer {
@@ -334,6 +340,7 @@ export class WebClientServer {
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
codeServerVersion: this._productService.codeServerVersion,
@@ -146,7 +146,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? {
...this._productService.extensionsGallery,
@@ -388,7 +395,9 @@ export class WebClientServer {
@@ -387,7 +394,9 @@ export class WebClientServer {
WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '',
WORKBENCH_WEB_BASE_URL: staticRoute,
WORKBENCH_NLS_URL,
@@ -157,7 +157,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
};
// DEV ---------------------------------------------------------------------------------------
@@ -425,7 +434,7 @@ export class WebClientServer {
@@ -424,7 +433,7 @@ export class WebClientServer {
'default-src \'self\';',
'img-src \'self\' https: data: blob:;',
'media-src \'self\';',
@@ -166,7 +166,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`,
'worker-src \'self\' data: blob:;',
@@ -498,3 +507,70 @@ export class WebClientServer {
@@ -497,3 +506,70 @@ export class WebClientServer {
return void res.end(data);
}
}
@@ -241,7 +241,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -57,6 +57,7 @@ export type ExtensionVirtualWorkspaceSup
@@ -65,6 +65,7 @@ export type ExtensionVirtualWorkspaceSup
export interface IProductConfiguration {
readonly codeServerVersion?: string
@@ -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
@@ -338,7 +338,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
@@ -583,17 +584,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
@@ -602,8 +592,8 @@ function readCookie(name: string): strin
if (!configElement || !configElementAttribute) {
throw new Error('Missing web configuration element');
}

View File

@@ -78,19 +78,19 @@ 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 {
@@ -135,6 +135,7 @@ export interface NativeParsedArgs {
'disable-chromium-sandbox'?: boolean;
sandbox?: boolean;
'enable-coi'?: boolean;
+ 'stdin-to-clipboard'?: boolean;
'unresponsive-sample-interval'?: string;
'unresponsive-sample-period'?: string;
'enable-rdp-display-tracking'?: boolean;
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.") },

View File

@@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
@@ -332,6 +332,10 @@ export class Extension implements IExten
@@ -341,6 +341,10 @@ export class Extension implements IExten
if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
return false;
}

View File

@@ -11,16 +11,16 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -12,7 +12,7 @@ import * as path from '../../base/common
import { IURITransformer } from '../../base/common/uriIpc.js';
import { getMachineId, getSqmMachineId, getdevDeviceId } from '../../base/node/id.js';
import { getMachineId, getSqmMachineId, getDevDeviceId } from '../../base/node/id.js';
import { Promises } from '../../base/node/pfs.js';
-import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, StaticRouter } from '../../base/parts/ipc/common/ipc.js';
+import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, ProxyChannel, StaticRouter } from '../../base/parts/ipc/common/ipc.js';
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);
@@ -272,6 +272,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'));
}
@@ -153,7 +153,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -26,6 +26,7 @@ import { URI } from '../../base/common/u
@@ -25,6 +25,7 @@ import { URI } from '../../base/common/u
import { streamToBuffer } from '../../base/common/buffer.js';
import { IProductConfiguration } from '../../base/common/product.js';
import { isString, Mutable } from '../../base/common/types.js';
@@ -161,7 +161,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
import { CharCode } from '../../base/common/charCode.js';
import { IExtensionManifest } from '../../platform/extensions/common/extensions.js';
import { ICSSDevelopmentService } from '../../platform/cssDev/node/cssDevService.js';
@@ -386,14 +387,22 @@ export class WebClientServer {
@@ -385,14 +386,22 @@ export class WebClientServer {
};
const cookies = cookie.parse(req.headers.cookie || '');
@@ -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 {
@@ -110,6 +111,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
) { }
@@ -272,7 +272,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
@@ -474,9 +474,6 @@ export class InstallAction extends Exten
@@ -475,9 +475,6 @@ export class InstallAction extends Exten
if (this.extension.isBuiltin) {
return;
}
@@ -282,7 +282,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
if (this.extension.state !== ExtensionState.Uninstalled) {
return;
}
@@ -781,7 +778,7 @@ export abstract class InstallInOtherServ
@@ -782,7 +779,7 @@ export abstract class InstallInOtherServ
}
if (isLanguagePackExtension(this.extension.local.manifest)) {
@@ -291,7 +291,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
}
// Prefers to run on UI
@@ -2071,17 +2068,6 @@ export class SetLanguageAction extends E
@@ -2073,17 +2070,6 @@ export class SetLanguageAction extends E
update(): void {
this.enabled = false;
this.class = SetLanguageAction.DisabledClass;
@@ -309,7 +309,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
}
override async run(): Promise<any> {
@@ -2098,7 +2084,6 @@ export class ClearLanguageAction extends
@@ -2100,7 +2086,6 @@ export class ClearLanguageAction extends
private static readonly DisabledClass = `${this.EnabledClass} disabled`;
constructor(
@@ -317,7 +317,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
@ILocaleService private readonly localeService: ILocaleService,
) {
super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false);
@@ -2108,17 +2093,6 @@ export class ClearLanguageAction extends
@@ -2110,17 +2095,6 @@ export class ClearLanguageAction extends
update(): void {
this.enabled = false;
this.class = ClearLanguageAction.DisabledClass;
@@ -335,28 +335,16 @@ 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
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
@@ -53,7 +53,7 @@ import './services/dialogs/browser/fileD
@@ -55,7 +55,7 @@ import './services/dialogs/browser/fileD
import './services/host/browser/browserHostService.js';
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';

View File

@@ -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 {
@@ -104,6 +106,8 @@ export interface ServerParsedArgs {
/* ----- code-server ----- */
'disable-update-check'?: boolean;
'auth'?: string;
@@ -112,7 +112,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -370,6 +370,8 @@ export class WebClientServer {
@@ -369,6 +369,8 @@ export class WebClientServer {
serverBasePath: basePath,
webviewEndpoint: staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
userDataPath: this._environmentService.userDataPath,
@@ -126,11 +126,11 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,11 +7,11 @@ import { Event } from '../../base/common
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js';
import { Disposable, DisposableStore, MutableDisposable } 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 { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext, IsSimulationContext } 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, AuxiliaryBarMaximizedContext, InAutomationContext } 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, InAutomationContext, 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
@@ -72,7 +72,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));
@@ -208,6 +208,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)
@@ -208,16 +208,16 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -40,6 +40,9 @@ export const HasWebFileSystemAccess = ne
@@ -39,6 +39,9 @@ export const EmbedderIdentifierContext =
export const EmbedderIdentifierContext = new RawContextKey<string | undefined>('embedderIdentifier', undefined, localize('embedderIdentifier', 'The identifier of the embedder according to the product service, if one is defined'));
export const InAutomationContext = new RawContextKey<boolean>('inAutomation', false, localize('inAutomation', "Whether VS Code is running under automation/smoke test"));
+export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
+export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
+
//#endregion
//#region < --- Window --- >
Index: code-server/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts
@@ -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);

View File

@@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
import { IEditorOpenContext, IEditorSerializer } from '../../../common/editor.js';
import { IWebviewElement, IWebviewService } from '../../webview/browser/webview.js';
import './gettingStartedColors.js';
@@ -874,6 +874,72 @@ export class GettingStartedPage extends
@@ -872,6 +872,72 @@ export class GettingStartedPage extends
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
);
@@ -101,7 +101,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
const leftColumn = $('.categories-column.categories-column-left', {},);
const rightColumn = $('.categories-column.categories-column-right', {},);
@@ -909,6 +975,9 @@ export class GettingStartedPage extends
@@ -907,6 +973,9 @@ export class GettingStartedPage extends
recentList.setLimit(5);
reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
}
@@ -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 {
@@ -108,6 +109,7 @@ export interface ServerParsedArgs {
'auth'?: string;
'disable-file-downloads'?: boolean;
'disable-file-uploads'?: boolean;
@@ -201,7 +201,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -374,6 +374,7 @@ export class WebClientServer {
@@ -373,6 +373,7 @@ export class WebClientServer {
userDataPath: this._environmentService.userDataPath,
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'],
@@ -214,15 +214,15 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,7 +7,7 @@ import { Event } from '../../base/common
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js';
import { Disposable, DisposableStore, MutableDisposable } 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 { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext, IsSimulationContext } 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, AuxiliaryBarMaximizedContext, InAutomationContext, 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, InAutomationContext, 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
@@ -211,6 +211,7 @@ export class WorkbenchContextKeysHandler
// code-server
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)
@@ -234,7 +234,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -42,6 +42,7 @@ export const EmbedderIdentifierContext =
@@ -41,6 +41,7 @@ export const InAutomationContext = new R
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);

View File

@@ -109,24 +109,6 @@ Index: code-server/lib/vscode/src/vs/base/common/processes.ts
];
const envKeys = Object.keys(env);
envKeys
Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
@@ -78,8 +78,11 @@ export class BrowserDialogHandler extend
async about(): Promise<void> {
const detailString = (useAgo: boolean): string => {
- return localize('aboutDetail',
- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
+ return localize('aboutCodeServerDetail',
+ "code-server: {0}",
+ this.productService.codeServerVersion ? `v${this.productService.codeServerVersion}` : 'Unknown'
+ ) + '\n' + localize('aboutDetail',
+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
this.productService.version || 'Unknown',
this.productService.commit || 'Unknown',
this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown',
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
===================================================================
--- /dev/null
@@ -204,7 +186,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -56,6 +56,8 @@ export type ExtensionVirtualWorkspaceSup
@@ -64,6 +64,8 @@ export type ExtensionVirtualWorkspaceSup
};
export interface IProductConfiguration {
@@ -269,7 +251,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -334,6 +334,7 @@ export class WebClientServer {
@@ -333,6 +333,7 @@ export class WebClientServer {
} : undefined;
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
@@ -281,7 +263,7 @@ Index: code-server/lib/vscode/src/server-main.ts
===================================================================
--- code-server.orig/lib/vscode/src/server-main.ts
+++ code-server/lib/vscode/src/server-main.ts
@@ -25,6 +25,9 @@ const __dirname = path.dirname(fileURLTo
@@ -22,6 +22,9 @@ import { IServerAPI } from './vs/server/
perf.mark('code/server/start');
(globalThis as any).vscodeServerStartTime = performance.now();
@@ -291,7 +273,7 @@ Index: code-server/lib/vscode/src/server-main.ts
// Do a quick parse to determine if a server or the cli needs to be started
const parsedArgs = minimist(process.argv.slice(2), {
boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'],
@@ -153,6 +156,7 @@ if (shouldSpawnCli) {
@@ -150,6 +153,7 @@ if (shouldSpawnCli) {
}
});
}
@@ -299,7 +281,7 @@ Index: code-server/lib/vscode/src/server-main.ts
function sanitizeStringArg(val: any): string | undefined {
if (Array.isArray(val)) { // if an argument is passed multiple times, minimist creates an array
@@ -286,3 +290,22 @@ function prompt(question: string): Promi
@@ -283,3 +287,22 @@ function prompt(question: string): Promi
});
});
}
@@ -310,7 +292,7 @@ Index: code-server/lib/vscode/src/server-main.ts
+ osLocale: 'en',
+ commit: product.commit,
+ userDataPath: '',
+ nlsMetadataPath: __dirname,
+ nlsMetadataPath: import.meta.dirname,
+ });
+ return loadCode(nlsConfiguration);
+}
@@ -322,3 +304,21 @@ Index: code-server/lib/vscode/src/server-main.ts
+if (!process.env.CODE_SERVER_PARENT_PID) {
+ start();
+}
Index: code-server/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
+++ code-server/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
@@ -45,8 +45,11 @@ export function createWorkbenchDialogOpt
export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } {
const detailString = (useAgo: boolean): string => {
- return localize('aboutDetail',
- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
+ return localize('aboutCodeServerDetail',
+ "code-server: {0}",
+ productService.codeServerVersion ? `v${productService.codeServerVersion}` : 'Unknown'
+ ) + '\n' + localize('aboutDetail',
+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
productService.version || 'Unknown',
productService.commit || 'Unknown',
productService.date ? `${productService.date}${useAgo ? ' (' + fromNow(new Date(productService.date), true) + ')' : ''}` : 'Unknown',

View File

@@ -18,7 +18,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -365,6 +365,7 @@ export class WebClientServer {
@@ -364,6 +364,7 @@ export class WebClientServer {
remoteAuthority,
serverBasePath: basePath,
webviewEndpoint: staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',

View File

@@ -8,7 +8,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -59,6 +59,7 @@ export interface IProductConfiguration {
@@ -67,6 +67,7 @@ export interface IProductConfiguration {
readonly codeServerVersion?: string
readonly rootEndpoint?: string
readonly updateEndpoint?: string
@@ -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
@@ -102,6 +103,7 @@ export const serverOptions: OptionDescri
export interface ServerParsedArgs {
/* ----- code-server ----- */
'disable-update-check'?: boolean;
@@ -40,7 +40,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -342,6 +342,7 @@ export class WebClientServer {
@@ -341,6 +341,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: rootBase,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,

View File

@@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
@@ -49,6 +49,16 @@ else if (globalThis._VSCODE_PRODUCT_JSON
@@ -49,6 +49,17 @@ else if (globalThis._VSCODE_PRODUCT_JSON
version: pkg.version
});
}
@@ -28,6 +28,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
+ extensionsGallery: env.EXTENSIONS_GALLERY ? JSON.parse(env.EXTENSIONS_GALLERY) : (product.extensionsGallery || {
+ serviceUrl: "https://open-vsx.org/vscode/gallery",
+ itemUrl: "https://open-vsx.org/vscode/item",
+ extensionUrlTemplate: "https://open-vsx.org/vscode/gallery/{publisher}/{name}/latest",
+ resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
+ controlUrl: "",
+ recommendationsUrl: "",
@@ -40,15 +41,15 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -327,7 +327,6 @@ export class WebClientServer {
@@ -326,7 +326,6 @@ export class WebClientServer {
const staticRoute = posix.join(basePath, this._productPath, STATIC_PATH);
const callbackRoute = posix.join(basePath, this._productPath, CALLBACK_PATH);
- const webExtensionRoute = posix.join(basePath, this._productPath, WEB_EXTENSION_PATH);
const resolveWorkspaceURI = (defaultLocation?: string) => defaultLocation && URI.file(path.resolve(defaultLocation)).with({ scheme: Schemas.vscodeRemote, authority: remoteAuthority });
const resolveWorkspaceURI = (defaultLocation?: string) => defaultLocation && URI.file(resolve(defaultLocation)).with({ scheme: Schemas.vscodeRemote, authority: remoteAuthority });
@@ -343,14 +342,7 @@ export class WebClientServer {
@@ -342,14 +341,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: rootBase,
embedderIdentifier: 'server-distro',

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
@@ -314,10 +314,7 @@ function extensionDescriptionArrayToMap(
@@ -321,10 +321,7 @@ function extensionDescriptionArrayToMap(
}
export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean {

View File

@@ -30,7 +30,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -60,6 +60,7 @@ export interface IProductConfiguration {
@@ -68,6 +68,7 @@ export interface IProductConfiguration {
readonly rootEndpoint?: string
readonly updateEndpoint?: string
readonly logoutEndpoint?: string
@@ -71,7 +71,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -343,6 +343,7 @@ export class WebClientServer {
@@ -342,6 +342,7 @@ export class WebClientServer {
rootEndpoint: rootBase,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? rootBase + '/logout' : undefined,
@@ -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
@@ -604,6 +605,39 @@ class WorkspaceProvider implements IWork
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
workspaceProvider: WorkspaceProvider.create(config),
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),

View File

@@ -6,7 +6,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -61,6 +61,10 @@ export interface IProductConfiguration {
@@ -69,6 +69,10 @@ export interface IProductConfiguration {
readonly updateEndpoint?: string
readonly logoutEndpoint?: string
readonly proxyEndpointTemplate?: string
@@ -54,7 +54,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -344,6 +344,10 @@ export class WebClientServer {
@@ -343,6 +343,10 @@ export class WebClientServer {
updateEndpoint: !this._environmentService.args['disable-update-check'] ? rootBase + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? rootBase + '/logout' : undefined,
proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? rootBase + '/proxy/{{port}}/',

View File

@@ -22,7 +22,7 @@ Index: code-server/lib/vscode/src/vs/platform/extensionManagement/node/extension
@IConfigurationService private readonly configurationService: IConfigurationService,
@IExtensionGalleryManifestService protected readonly extensionGalleryManifestService: IExtensionGalleryManifestService,
@IProductService productService: IProductService,
@@ -331,8 +333,7 @@ export class ExtensionManagementService
@@ -339,8 +341,7 @@ export class ExtensionManagementService
private async downloadExtension(extension: IGalleryExtension, operation: InstallOperation, verifySignature: boolean, clientTargetPlatform?: TargetPlatform): Promise<{ readonly location: URI; readonly verificationStatus: ExtensionSignatureVerificationCode | undefined }> {
if (verifySignature) {

View File

@@ -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`),

View File

@@ -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';
@@ -423,7 +424,28 @@ async function startExtensionHostProcess
@@ -449,7 +450,28 @@ async function startExtensionHostProcess
);
// rewrite onTerminate-function to be a proper shutdown

View File

@@ -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
@@ -166,11 +168,23 @@ export async function setupServerService
const requestService = new RequestService('remote', configurationService, environmentService, logService);
services.set(IRequestService, requestService);
@@ -134,7 +134,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -348,6 +348,8 @@ export class WebClientServer {
@@ -347,6 +347,8 @@ export class WebClientServer {
scope: vscodeBase + '/',
path: rootBase + '/_static/out/browser/serviceWorker.js',
},
@@ -147,7 +147,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -65,6 +65,7 @@ export interface IProductConfiguration {
@@ -73,6 +73,7 @@ export interface IProductConfiguration {
readonly path: string;
readonly scope: string;
}

View File

@@ -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 {
@@ -112,6 +113,7 @@ export interface ServerParsedArgs {
'disable-file-uploads'?: boolean;
'disable-getting-started-override'?: boolean,
'locale'?: string
@@ -24,7 +24,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -339,6 +339,14 @@ export class WebClientServer {
@@ -338,6 +338,14 @@ export class WebClientServer {
scopes: [['user:email'], ['repo']]
} : undefined;
@@ -39,7 +39,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: rootBase,
@@ -353,6 +361,7 @@ export class WebClientServer {
@@ -352,6 +360,7 @@ export class WebClientServer {
telemetryEndpoint: this._productService.telemetryEndpoint,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,

View File

@@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -58,6 +58,7 @@ export type ExtensionVirtualWorkspaceSup
@@ -66,6 +66,7 @@ export type ExtensionVirtualWorkspaceSup
export interface IProductConfiguration {
readonly codeServerVersion?: string
readonly rootEndpoint?: string
@@ -105,7 +105,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -341,6 +341,7 @@ export class WebClientServer {
@@ -340,6 +340,7 @@ export class WebClientServer {
const productConfiguration: Partial<Mutable<IProductConfiguration>> = {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: rootBase,
@@ -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
@@ -98,6 +100,8 @@ export const serverOptions: OptionDescri
};
export interface ServerParsedArgs {

View File

@@ -54,7 +54,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -361,6 +361,7 @@ export class WebClientServer {
@@ -360,6 +360,7 @@ export class WebClientServer {
const workbenchWebConfiguration = {
remoteAuthority,
serverBasePath: basePath,
@@ -70,29 +70,21 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
- content="default-src 'none'; script-src 'sha256-nlLyDpnjtftJG2xvXh2vuy77l7xFTjfOz7Jnj1iXNmA=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-ap/AtocvSWp0rrxaO19DJy/nOpazT6M5Cv9utUWe7MA=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
- content="default-src 'none'; script-src 'sha256-ZcIhtIuU4M9PbKfs7w/CLqHimFJRK8L7mYTXOfiUv0I=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-dVbEBqfV68sWYG05nAX+55pv4dls0VnI6ZDMMV/0GYQ=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming -->
@@ -349,6 +349,12 @@
<meta name="viewport"
@@ -256,7 +256,7 @@
}
const hostname = location.hostname;
+ // It is safe to run if we are on the same host.
+ const parent = new URL(parentOrigin)
+ if (parent.hostname === hostname) {
+ return start(parentOrigin)
+ }
+
if (!crypto.subtle) {
// cannot validate, not running in a secure context
throw new Error(`'crypto.subtle' is not available so webviews will not work. This is likely because the editor is not running in a secure context (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).`);
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
@@ -343,6 +343,12 @@
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
@@ -370,6 +370,12 @@
const hostname = location.hostname;

Binary file not shown.

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -15,7 +15,8 @@ body {
color: #111;
color: light-dark(#111, #ddd);
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji",
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol";
overflow: hidden;
}

View File

@@ -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[] => {

View File

@@ -1,9 +1,8 @@
import { field, logger } from "@coder/logger"
import * as express from "express"
import * as expressCore from "express-serve-static-core"
import * as http from "http"
import * as net from "net"
import * as qs from "qs"
import qs from "qs"
import { Disposable } from "../common/emitter"
import { CookieKeys, HttpCode, HttpError } from "../common/http"
import { normalize } from "../common/util"
@@ -185,12 +184,7 @@ export const constructRedirectPath = (req: express.Request, query: qs.ParsedQs,
* preserved. `to` should be a simple path without any query parameters
* `override` will merge with the existing query (use `undefined` to unset).
*/
export const redirect = (
req: express.Request,
res: express.Response,
to: string,
override: expressCore.Query = {},
): void => {
export const redirect = (req: express.Request, res: express.Response, to: string, override: qs.ParsedQs = {}): void => {
const query = Object.assign({}, req.query, override)
Object.keys(override).forEach((key) => {
if (typeof override[key] === "undefined") {

View File

@@ -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

View File

@@ -1,15 +1,16 @@
import { field, logger } from "@coder/logger"
import http from "http"
import * as os from "os"
import * as path from "path"
import { Disposable } from "../common/emitter"
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"
import * as os from "os"
/**
* Return true if the user passed an extension-related VS Code flag.
@@ -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}`)
}

View File

@@ -3,10 +3,10 @@ import express from "express"
import { promises as fs } from "fs"
import path from "path"
import { HttpCode } from "../../common/http"
import type { WebsocketRequest } from "../wsRouter"
import { rootPath } from "../constants"
import { replaceTemplates } from "../http"
import { escapeHtml, getMediaMime } from "../util"
import type { WebsocketRequest } from "../wsRouter"
interface ErrorWithStatusCode {
statusCode: number

View File

@@ -14,8 +14,8 @@ import { Heart } from "../heart"
import { redirect } from "../http"
import { CoderSettings, SettingsProvider } from "../settings"
import { UpdateProvider } from "../update"
import type { WebsocketRequest } from "../wsRouter"
import { getMediaMime, paths } from "../util"
import type { WebsocketRequest } from "../wsRouter"
import * as domainProxy from "./domainProxy"
import { errorHandler, wsErrorHandler } from "./errors"
import * as health from "./health"

View File

@@ -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")

View File

@@ -4,8 +4,8 @@ import * as express from "express"
import { promises as fs } from "fs"
import * as http from "http"
import * as net from "net"
import * as path from "path"
import * as os from "os"
import * as path from "path"
import { logError } from "../../common/util"
import { CodeArgs, toCodeArgs } from "../cli"
import { isDevMode, vsRootPath } from "../constants"
@@ -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,

View File

@@ -1,5 +1,5 @@
import { logger } from "@coder/logger"
import { Query } from "express-serve-static-core"
import type { ParsedQs } from "qs"
import { promises as fs } from "fs"
export type Settings = { [key: string]: Settings | string | boolean | number }
@@ -17,7 +17,7 @@ export class SettingsProvider<T> {
public async read(): Promise<T> {
try {
const raw = (await fs.readFile(this.settingsPath, "utf8")).trim()
return raw ? JSON.parse(raw) : {}
return raw ? JSON.parse(raw) : ({} as T)
} catch (error: any) {
if (error.code !== "ENOENT") {
logger.warn(error.message)
@@ -52,5 +52,5 @@ export interface UpdateSettings {
* Global code-server settings.
*/
export interface CoderSettings extends UpdateSettings {
query?: Query
query?: ParsedQs
}

View File

@@ -2,8 +2,9 @@ import { logger } from "@coder/logger"
import express from "express"
import * as http from "http"
import * as path from "path"
import { HttpCode } from "../common/http"
import { HttpCode, HttpError } from "../common/http"
import { listen } from "./app"
import { errorHandler } from "./routes/errors"
import { canConnect } from "./util"
export interface EditorSessionEntry {
@@ -44,24 +45,18 @@ export async function makeEditorSessionManagerServer(
async (req, res) => {
const filePath = req.query.filePath
if (!filePath) {
res.status(HttpCode.BadRequest).send("filePath is required")
return
}
try {
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
const response: GetSessionResponse = { socketPath }
res.json(response)
} catch (error: unknown) {
res.status(HttpCode.ServerError).send(error)
throw new HttpError("filePath is required", HttpCode.BadRequest)
}
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
const response: GetSessionResponse = { socketPath }
res.json(response)
},
)
router.post<{}, string, AddSessionRequest | undefined>("/add-session", async (req, res) => {
const entry = req.body?.entry
if (!entry) {
res.status(400).send("entry is required")
return
throw new HttpError("entry is required", HttpCode.BadRequest)
}
editorSessionManager.addSession(entry)
res.status(200).send("session added")
@@ -70,13 +65,14 @@ export async function makeEditorSessionManagerServer(
router.post<{}, string, DeleteSessionRequest | undefined>("/delete-session", async (req, res) => {
const socketPath = req.body?.socketPath
if (!socketPath) {
res.status(400).send("socketPath is required")
return
throw new HttpError("socketPath is required", HttpCode.BadRequest)
}
editorSessionManager.deleteSession(socketPath)
res.status(200).send("session deleted")
})
router.use(errorHandler)
const server = http.createServer(router)
try {
await listen(server, { socket: codeServerSocketPath })

421
test/package-lock.json generated
View File

@@ -11,7 +11,6 @@
"@types/jest": "^27.0.2",
"@types/jsdom": "^16.2.13",
"@types/node-fetch": "^2.5.8",
"@types/supertest": "^2.0.11",
"@types/wtfnode": "^0.7.0",
"argon2": "^0.28.0",
"extract-zip": "^2.0.1",
@@ -20,7 +19,6 @@
"jsdom": "^16.4.0",
"node-fetch": "^2.6.7",
"playwright": "^1.46.0",
"supertest": "^6.1.6",
"ts-jest": "^27.0.7",
"wtfnode": "^0.9.1"
}
@@ -1104,13 +1102,6 @@
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/cookiejar": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
"integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -1171,13 +1162,6 @@
"@types/tough-cookie": "*"
}
},
"node_modules/@types/methods": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
"integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
@@ -1220,29 +1204,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/superagent": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz",
"integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/cookiejar": "^2.1.5",
"@types/methods": "^1.1.4",
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/@types/supertest": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.16.tgz",
"integrity": "sha512-6c2ogktZ06tr2ENoZivgm7YnprnhYE4ZoXGMY+oA7IuAf17M8FWvujXZGmxLv8y0PTyts4x5A+erSwVUFA8XSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/superagent": "*"
}
},
"node_modules/@types/tough-cookie": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
@@ -1464,13 +1425,6 @@
"sprintf-js": "~1.0.2"
}
},
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"dev": true,
"license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -1689,24 +1643,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/callsites": {
@@ -1883,16 +1831,6 @@
"node": ">= 0.8"
}
},
"node_modules/component-emitter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1914,13 +1852,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/cookiejar": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
"dev": true,
"license": "MIT"
},
"node_modules/cross-fetch": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
@@ -2030,24 +1961,6 @@
"node": ">=0.10.0"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -2085,17 +1998,6 @@
"node": ">=8"
}
},
"node_modules/dezalgo": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
"dev": true,
"license": "ISC",
"dependencies": {
"asap": "^2.0.0",
"wrappy": "1"
}
},
"node_modules/diff-sequences": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
@@ -2130,6 +2032,21 @@
"node": ">=8"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/electron-to-chromium": {
"version": "1.5.32",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz",
@@ -2178,14 +2095,11 @@
}
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
@@ -2200,6 +2114,35 @@
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -2366,13 +2309,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/fast-safe-stringify": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
"dev": true,
"license": "MIT"
},
"node_modules/fb-watchman": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
@@ -2421,36 +2357,22 @@
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"dev": true,
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/formidable": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
"integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"dezalgo": "^1.0.4",
"hexoid": "^1.0.0",
"once": "^1.4.0",
"qs": "^6.11.0"
},
"funding": {
"url": "https://ko-fi.com/tunnckoCore/commissions"
}
},
"node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@@ -2559,17 +2481,22 @@
}
},
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -2588,6 +2515,20 @@
"node": ">=8.0.0"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
@@ -2637,13 +2578,13 @@
}
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"license": "MIT",
"dependencies": {
"get-intrinsic": "^1.1.3"
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -2666,23 +2607,10 @@
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2692,12 +2620,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
@@ -2725,16 +2656,6 @@
"node": ">= 0.4"
}
},
"node_modules/hexoid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/html-encoding-sniffer": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
@@ -3764,15 +3685,17 @@
}
},
"node_modules/jsdom/node_modules/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz",
"integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.35"
},
"engines": {
"node": ">= 6"
@@ -3918,6 +3841,16 @@
"tmpl": "1.0.5"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -3925,16 +3858,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -3949,19 +3872,6 @@
"node": ">=8.6"
}
},
"node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"dev": true,
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -4216,19 +4126,6 @@
"node": ">=0.10.0"
}
},
"node_modules/object-inspect": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -4531,22 +4428,6 @@
"node": ">=6"
}
},
"node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@@ -4722,24 +4603,6 @@
"dev": true,
"license": "ISC"
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -4763,25 +4626,6 @@
"node": ">=8"
}
},
"node_modules/side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -4932,43 +4776,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/superagent": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz",
"integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==",
"deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net",
"dev": true,
"license": "MIT",
"dependencies": {
"component-emitter": "^1.3.0",
"cookiejar": "^2.1.4",
"debug": "^4.3.4",
"fast-safe-stringify": "^2.1.1",
"form-data": "^4.0.0",
"formidable": "^2.1.2",
"methods": "^1.1.2",
"mime": "2.6.0",
"qs": "^6.11.0",
"semver": "^7.3.8"
},
"engines": {
"node": ">=6.4.0 <13 || >=14"
}
},
"node_modules/supertest": {
"version": "6.3.4",
"resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz",
"integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==",
"dev": true,
"license": "MIT",
"dependencies": {
"methods": "^1.1.2",
"superagent": "^8.1.2"
},
"engines": {
"node": ">=6.4.0"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",

View File

@@ -7,7 +7,6 @@
"@types/jest": "^27.0.2",
"@types/jsdom": "^16.2.13",
"@types/node-fetch": "^2.5.8",
"@types/supertest": "^2.0.11",
"@types/wtfnode": "^0.7.0",
"argon2": "^0.28.0",
"extract-zip": "^2.0.1",
@@ -16,7 +15,6 @@
"jsdom": "^16.4.0",
"node-fetch": "^2.6.7",
"playwright": "^1.46.0",
"supertest": "^6.1.6",
"ts-jest": "^27.0.7",
"wtfnode": "^0.9.1"
},

View File

@@ -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
View 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
View 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)
})
})
})

View File

@@ -29,7 +29,7 @@ describe("settings", () => {
const settings = new SettingsProvider<CoderSettings>(pathToMockSettingsFile)
await settings.read()
// This happens when we can't parse a JSON (usually error in file)
expect(logger.warn).toHaveBeenCalledWith(expect.stringMatching(/Unexpected token/))
expect(logger.warn).toHaveBeenCalledWith(expect.stringMatching(/Expected ':'/))
})
})
describe("with invalid settings file path", () => {