Compare commits

..

1 Commits

Author SHA1 Message Date
Akash Satheesan
c041986976 chore(release): bump version to 3.11.0 2021-07-15 00:50:40 +05:30
69 changed files with 652 additions and 1235 deletions

View File

@@ -62,11 +62,6 @@ Additionally, collecting core dumps (you may need to enable them first) if
code-server crashes can be helpful. code-server crashes can be helpful.
--> -->
<!--
If you're having issues with installation please include the installation logs
i.e. the output of `yarn global add code-server` if you installed with `yarn`
-->
## Screenshot ## Screenshot
<!-- Ideally provide a screenshot, gif, video or screen recording. --> <!-- Ideally provide a screenshot, gif, video or screen recording. -->

3
.github/codecov.yml vendored
View File

@@ -5,8 +5,7 @@ codecov:
coverage: coverage:
precision: 2 precision: 2
round: down round: down
range: "40...70" range: "70...100"
patch: off
parsers: parsers:
gcov: gcov:

32
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
time: "11:00"
ignore:
# GitHub always delivers the latest versions for each major
# release tag, so handle updates manually
- dependency-name: "actions/*"
- dependency-name: "github/codeql-action/*"
- dependency-name: "microsoft/playwright-github-action"
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
time: "11:00"
ignore:
- dependency-name: "@types/node"
update-types: ["version-update:semver-major"]
- dependency-name: "xdg-basedir"
# 5.0.0 has breaking changes as they switch to named exports
# and convert the module to ESM
# We can't use it until we switch to ESM across the project
# See release notes: https://github.com/sindresorhus/xdg-basedir/releases/tag/v5.0.0
versions: ["5.x"]
- dependency-name: "limiter"
# 2.0.0 has breaking changes
# so we can't update yet.
versions: ["2.x"]

View File

@@ -352,8 +352,8 @@ jobs:
with: with:
node-version: "14" node-version: "14"
- name: Install playwright OS dependencies - name: Install playwright
run: npx playwright install-deps uses: microsoft/playwright-github-action@v1
- name: Fetch dependencies from cache - name: Fetch dependencies from cache
id: cache-yarn id: cache-yarn
@@ -402,6 +402,73 @@ jobs:
- name: Remove release packages and test artifacts - name: Remove release packages and test artifacts
run: rm -rf ./release-packages ./test/test-results run: rm -rf ./release-packages ./test/test-results
# Builds both amd64 and arm64 images
docker-images:
runs-on: ubuntu-latest
needs: [package-linux-amd64, package-linux-arm64]
steps:
- uses: actions/checkout@v2
- name: Download release package
uses: actions/download-artifact@v2
with:
name: release-packages
path: ./release-packages
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Run ./ci/steps/build-docker-image.sh
run: ./ci/steps/build-docker-image.sh
- name: Upload release images
uses: actions/upload-artifact@v2
with:
name: release-images
path: ./release-images
trivy-scan-image:
runs-on: ubuntu-20.04
needs: docker-images
# NOTE@jsjoeio: disabling due to a memory issue upstream
# See: https://github.com/github/codeql-action/issues/528
if: 1 == 2
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Download release images
uses: actions/download-artifact@v2
with:
name: release-images
path: ./release-images
- name: Run Trivy vulnerability scanner in image mode
# Commit SHA for v0.0.17
uses: aquasecurity/trivy-action@ac8de07fd168680dd0331bef43681c0e150e9ad1
with:
input: "./release-images/code-server-amd64-*.tar"
scan-type: "image"
ignore-unfixed: true
format: "template"
template: "@/contrib/sarif.tpl"
output: "trivy-image-results.sarif"
severity: "HIGH,CRITICAL"
- name: Debug Trivy SARIF file
run: cat trivy-image-results.sarif && ls -l trivy-image-results.sarif
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: "trivy-image-results.sarif"
# We have to use two trivy jobs
# because GitHub only allows
# codeql/upload-sarif action per job
trivy-scan-repo: trivy-scan-repo:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
@@ -409,7 +476,7 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Run Trivy vulnerability scanner in repo mode - name: Run Trivy vulnerability scanner in repo mode
#Commit SHA for v0.0.17 #Commit SHA for v0.0.17
uses: aquasecurity/trivy-action@9438b49cc3156b2e8c77c1ba8ffbaa3bae24e3c2 uses: aquasecurity/trivy-action@ac8de07fd168680dd0331bef43681c0e150e9ad1
with: with:
scan-type: "fs" scan-type: "fs"
scan-ref: "." scan-ref: "."

View File

@@ -1,28 +0,0 @@
name: Publish on Docker
on:
# Shows the manual trigger in GitHub UI
# helpful as a back-up in case the GitHub Actions Workflow fails
workflow_dispatch:
release:
types: [published]
jobs:
docker-images:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Run ./ci/steps/docker-buildx-push.sh
run: ./ci/steps/docker-buildx-push.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}

View File

@@ -1,4 +1,4 @@
name: Publish on npm and brew name: publish
on: on:
# Shows the manual trigger in GitHub UI # Shows the manual trigger in GitHub UI
@@ -22,6 +22,20 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# NOTE: this job requires curl, jq and docker
# All of them are included in ubuntu-latest.
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run ./ci/steps/push-docker-manifest.sh
run: ./ci/steps/push-docker-manifest.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
homebrew: homebrew:
# The newest version of code-server needs to be available on npm when this runs # The newest version of code-server needs to be available on npm when this runs
# otherwise, it will 404 and won't open a PR to bump version on homebrew/homebrew-core # otherwise, it will 404 and won't open a PR to bump version on homebrew/homebrew-core

View File

@@ -1 +0,0 @@
14

1
.nvmrc
View File

@@ -1 +0,0 @@
.node-version

View File

@@ -78,8 +78,8 @@ You can disable minification by setting `MINIFY=`.
This directory contains the release docker container image. This directory contains the release docker container image.
- [./ci/steps/build-docker-buildx-push.sh](./ci/steps/docker-buildx-push.sh) - [./ci/steps/build-docker-image.sh](./ci/steps/build-docker-image.sh)
- Builds the release containers with tags `codercom/code-server-$ARCH:$VERSION` for amd64 and arm64 with `docker buildx` and pushes them. - Builds the release containers with tags `codercom/code-server-$ARCH:$VERSION` for amd64 and arm64 with `docker buildx`.
- Assumes debian releases are ready in `./release-packages`. - Assumes debian releases are ready in `./release-packages`.
## images ## images
@@ -107,8 +107,8 @@ Helps avoid clobbering the CI configuration.
release packages into `./release-packages`. release packages into `./release-packages`.
- [./steps/publish-npm.sh](./steps/publish-npm.sh) - [./steps/publish-npm.sh](./steps/publish-npm.sh)
- Grabs the `npm-package` release artifact for the current commit and publishes it on npm. - Grabs the `npm-package` release artifact for the current commit and publishes it on npm.
- [./steps/docker-buildx-push.sh](./steps/docker-buildx-push.sh) - [./steps/build-docker-image.sh](./steps/build-docker-image.sh)
- Builds the docker image and then pushes it. - Builds the docker image and then saves it into `./release-images/code-server-$ARCH-$VERSION.tar`.
- [./steps/push-docker-manifest.sh](./steps/push-docker-manifest.sh) - [./steps/push-docker-manifest.sh](./steps/push-docker-manifest.sh)
- Loads all images in `./release-images` and then builds and pushes a multi architecture - Loads all images in `./release-images` and then builds and pushes a multi architecture
docker manifest for the amd64 and arm64 images to `codercom/code-server:$VERSION` and docker manifest for the amd64 and arm64 images to `codercom/code-server:$VERSION` and

View File

@@ -3,7 +3,7 @@ set -euo pipefail
main() { main() {
cd "$(dirname "$0")/../.." cd "$(dirname "$0")/../.."
cd test/unit/node/test-plugin cd test/unit/test-plugin
make -s out/index.js make -s out/index.js
# We must keep jest in a sub-directory. See ../../test/package.json for more # We must keep jest in a sub-directory. See ../../test/package.json for more
# information. We must also run it from the root otherwise coverage will not # information. We must also run it from the root otherwise coverage will not

View File

@@ -20,4 +20,4 @@ version: 1.0.3
# This is the version number of the application being deployed. This version number should be # 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 # 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. # follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 3.11.1 appVersion: 3.11.0

View File

@@ -1,6 +1,6 @@
# code-server # code-server
![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 3.11.1](https://img.shields.io/badge/AppVersion-3.11.1-informational?style=flat-square) ![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 3.11.0](https://img.shields.io/badge/AppVersion-3.11.0-informational?style=flat-square)
[code-server](https://github.com/cdr/code-server) code-server is VS Code running [code-server](https://github.com/cdr/code-server) code-server is VS Code running
on a remote server, accessible through the browser. on a remote server, accessible through the browser.
@@ -73,7 +73,7 @@ and their default values.
| hostnameOverride | string | `""` | | | hostnameOverride | string | `""` | |
| image.pullPolicy | string | `"Always"` | | | image.pullPolicy | string | `"Always"` | |
| image.repository | string | `"codercom/code-server"` | | | image.repository | string | `"codercom/code-server"` | |
| image.tag | string | `"3.11.1"` | | | image.tag | string | `"3.11.0"` | |
| imagePullSecrets | list | `[]` | | | imagePullSecrets | list | `[]` | |
| ingress.enabled | bool | `false` | | | ingress.enabled | bool | `false` | |
| nameOverride | string | `""` | | | nameOverride | string | `""` | |

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image: image:
repository: codercom/code-server repository: codercom/code-server
tag: '3.11.1' tag: '3.11.0'
pullPolicy: Always pullPolicy: Always
imagePullSecrets: [] imagePullSecrets: []

View File

@@ -57,12 +57,12 @@ arch() {
# https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs # https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
get_artifacts_url() { get_artifacts_url() {
local artifacts_url local artifacts_url
local workflow_runs_url="repos/:owner/:repo/actions/workflows/ci.yaml/runs?event=pull_request"
local version_branch="v$VERSION" local version_branch="v$VERSION"
local workflow_runs_url="repos/:owner/:repo/actions/workflows/ci.yaml/runs?event=pull_request&branch=$version_branch"
artifacts_url=$(gh api "$workflow_runs_url" | jq -r ".workflow_runs[] | select(.head_branch == \"$version_branch\") | .artifacts_url" | head -n 1) artifacts_url=$(gh api "$workflow_runs_url" | jq -r ".workflow_runs[] | select(.head_branch == \"$version_branch\") | .artifacts_url" | head -n 1)
if [[ -z "$artifacts_url" ]]; then if [[ -z "$artifacts_url" ]]; then
echo >&2 "ERROR: artifacts_url came back empty" echo >&2 "ERROR: artifacts_url came back empty"
echo >&2 "We looked for a successful run triggered by a pull_request with for code-server version: $VERSION and a branch named $version_branch" echo >&2 "We looked for a successful run triggered by a pull_request with for code-server version: $code_server_version and a branch named $version_branch"
echo >&2 "URL used for gh API call: $workflow_runs_url" echo >&2 "URL used for gh API call: $workflow_runs_url"
exit 1 exit 1
fi fi

View File

@@ -7,11 +7,19 @@ variable "VERSION" {
} }
group "default" { group "default" {
targets = ["code-server"] targets = ["code-server-amd64", "code-server-arm64"]
} }
target "code-server" { target "code-server-amd64" {
dockerfile = "ci/release-image/Dockerfile" dockerfile = "ci/release-image/Dockerfile"
tags = ["docker.io/codercom/code-server:${VERSION}"] tags = ["docker.io/codercom/code-server-amd64:${VERSION}"]
platforms = ["linux/amd64", "linux/arm64"] platforms = ["linux/amd64"]
output = ["type=tar,dest=./release-images/code-server-amd64-${VERSION}.tar"]
}
target "code-server-arm64" {
dockerfile = "ci/release-image/Dockerfile"
tags = ["docker.io/codercom/code-server-arm64:${VERSION}"]
platforms = ["linux/arm64"]
output = ["type=tar,dest=./release-images/code-server-arm64-${VERSION}.tar"]
} }

View File

@@ -19,10 +19,10 @@ main() {
echo "Adding Homebrew/homebrew-core as $(upstream)" echo "Adding Homebrew/homebrew-core as $(upstream)"
git remote add upstream https://github.com/Homebrew/homebrew-core.git git remote add upstream https://github.com/Homebrew/homebrew-core.git
echo "Fetching upstream Homebrew/hombrew-core commits" echo "Fetching upstream commits..."
git fetch upstream git fetch upstream
echo "Merging in latest Homebrew/homebrew-core changes" echo "Merging in latest changes"
git merge upstream/master git merge upstream/master
echo "Pushing changes to cdrci/homebrew-core fork on GitHub" echo "Pushing changes to cdrci/homebrew-core fork on GitHub"
@@ -37,15 +37,7 @@ main() {
# Find the docs for bump-formula-pr here # Find the docs for bump-formula-pr here
# https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/bump-formula-pr.rb#L18 # https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/bump-formula-pr.rb#L18
local output brew bump-formula-pr --force --version="${VERSION}" code-server --no-browse --no-audit
if ! output=$(brew bump-formula-pr --version="${VERSION}" code-server --no-browse --no-audit 2>&1); then
if [[ $output == *"Duplicate PRs should not be opened"* ]]; then
echo "$VERSION is already submitted"
else
echo "$output"
exit 1
fi
fi
# Clean up and remove homebrew-core # Clean up and remove homebrew-core
cd .. cd ..

12
ci/steps/build-docker-image.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
source ./ci/lib.sh
mkdir -p release-images
docker buildx bake -f ci/release-image/docker-bake.hcl
}
main "$@"

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# See if this version already exists on Docker Hub.
function version_exists() {
local output
output=$(curl --silent "https://index.docker.io/v1/repositories/codercom/code-server/tags/$VERSION")
if [[ $output == "Tag not found" ]]; then
return 1
else
return 0
fi
}
main() {
cd "$(dirname "$0")/../.."
# ci/lib.sh sets VERSION and provides download_artifact here
source ./ci/lib.sh
if version_exists; then
echo "$VERSION is already pushed"
return
fi
# Download the release-packages artifact
download_artifact release-packages ./release-packages
# Login to Docker
if [[ ${CI-} ]]; then
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
fi
docker buildx bake -f ci/release-image/docker-bake.hcl --push
}
main "$@"

View File

@@ -5,14 +5,6 @@ main() {
cd "$(dirname "$0")/../.." cd "$(dirname "$0")/../.."
source ./ci/lib.sh source ./ci/lib.sh
# npm view won't exit with non-zero so we have to check the output.
local hasVersion
hasVersion=$(npm view "code-server@$VERSION" version)
if [[ $hasVersion == "$VERSION" ]]; then
echo "$VERSION is already published"
return
fi
if [[ ${CI-} ]]; then if [[ ${CI-} ]]; then
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
fi fi

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
main() {
cd "$(dirname "$0")/../.."
source ./ci/lib.sh
download_artifact release-images ./release-images
if [[ ${CI-} ]]; then
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
fi
for img in ./release-images/*; do
docker load -i "$img"
done
# We have to ensure the amd64 and arm64 images exist on the remote registry
# in order to build the manifest.
# We don't put the arch in the tag to avoid polluting the main repository.
# These other repositories are private so they don't pollute our organization namespace.
docker push "codercom/code-server-amd64:$VERSION"
docker push "codercom/code-server-arm64:$VERSION"
export DOCKER_CLI_EXPERIMENTAL=enabled
docker manifest create "codercom/code-server:$VERSION" \
"codercom/code-server-amd64:$VERSION" \
"codercom/code-server-arm64:$VERSION"
docker manifest push --purge "codercom/code-server:$VERSION"
docker manifest create "codercom/code-server:latest" \
"codercom/code-server-amd64:$VERSION" \
"codercom/code-server-arm64:$VERSION"
docker manifest push --purge "codercom/code-server:latest"
}
main "$@"

View File

@@ -29,7 +29,6 @@ Here is what is needed:
- `node` v14.x - `node` v14.x
- `git` v2.x or greater - `git` v2.x or greater
- [`git-lfs`](https://git-lfs.github.com)
- [`yarn`](https://classic.yarnpkg.com/en/) - [`yarn`](https://classic.yarnpkg.com/en/)
- Used to install JS packages and run scripts - Used to install JS packages and run scripts
- [`nfpm`](https://classic.yarnpkg.com/en/) - [`nfpm`](https://classic.yarnpkg.com/en/)
@@ -143,7 +142,7 @@ Our unit tests are written in TypeScript and run using
These live under [test/unit](../test/unit). These live under [test/unit](../test/unit).
We use unit tests for functions and things that can be tested in isolation. The file structure is modeled closely after `/src` so it's easy for people to know where test files should live. We use unit tests for functions and things that can be tested in isolation.
### Integration tests ### Integration tests

View File

@@ -28,6 +28,7 @@
- [What's the difference between code-server and Theia?](#whats-the-difference-between-code-server-and-theia) - [What's the difference between code-server and Theia?](#whats-the-difference-between-code-server-and-theia)
- [What's the difference between code-server and VS Code Codespaces?](#whats-the-difference-between-code-server-and-vs-code-codespaces) - [What's the difference between code-server and VS Code Codespaces?](#whats-the-difference-between-code-server-and-vs-code-codespaces)
- [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation) - [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation)
- [Enterprise](#enterprise)
- [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server) - [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server)
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -389,13 +390,20 @@ Codespaces web dashboard instead of connecting directly to it.
On the other hand, code-server is free, open-source, and can be run on any On the other hand, code-server is free, open-source, and can be run on any
machine with few limitations. machine with few limitations.
<<<<<<< HEAD
## Does code-server have any security login validation? ## Does code-server have any security login validation?
code-server supports setting a single password and limits logins to two per code-server only supports a single password and limits logins to two per minute plus twelve per hour.
minute plus an additional twelve per hour.
## Enterprise
=======
## Are there community projects involving code-server? ## Are there community projects involving code-server?
> > > > > > > Edit code-server docs
Visit the [awesome-code-server](https://github.com/cdr/awesome-code-server) Visit the [awesome-code-server](https://github.com/cdr/awesome-code-server)
repository to view community projects and guides with code-server! Feel free to repository to view community projects and guides with code-server! Feel free to
add your own! add your own!

View File

@@ -1,6 +1,6 @@
# code-server # code-server
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/cdr/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://cdr.co/join-community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/cdr/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/cdr/code-server) [![See v3.11.1 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v3.11.1%20&color=blue)](https://github.com/cdr/code-server/tree/v3.11.1/docs) [!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/cdr/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://cdr.co/join-community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/cdr/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/cdr/code-server) [![See v3.11.0 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v3.11.0%20&color=blue)](https://github.com/cdr/code-server/tree/v3.11.0/docs)
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and
access it in the browser. access it in the browser.
@@ -30,7 +30,7 @@ There are three ways to get started:
automates most of the process. The script uses the system package manager if automates most of the process. The script uses the system package manager if
possible. possible.
2. Manually [installing 2. Manually [installing
code-server](https://coder.com/docs/code-server/v3.11.1/install) code-server](https://coder.com/docs/code-server/v3.11.0/install)
3. Using our one-click buttons and guides to [deploy code-server to a cloud 3. Using our one-click buttons and guides to [deploy code-server to a cloud
provider](https://github.com/cdr/deploy-code-server) ⚡ provider](https://github.com/cdr/deploy-code-server) ⚡
@@ -51,7 +51,7 @@ When done, the install script prints out instructions for running and starting
code-server. code-server.
We also have an in-depth [setup and We also have an in-depth [setup and
configuration](https://coder.com/docs/code-server/v3.11.1/guide) guide. configuration](https://coder.com/docs/code-server/v3.11.0/guide) guide.
### code-server --link ### code-server --link
@@ -71,11 +71,11 @@ Proxying code-server, you can access your IDE at https://example.cdr.co
## Questions? ## Questions?
See answers to [frequently asked See answers to [frequently asked
questions](https://coder.com/docs/code-server/v3.11.1/FAQ). questions](https://coder.com/docs/code-server/v3.11.0/FAQ).
## Want to help? ## Want to help?
See [Contributing](https://coder.com/docs/code-server/v3.11.1/CONTRIBUTING) for See [Contributing](https://coder.com/docs/code-server/v3.11.0/CONTRIBUTING) for
details. details.
## Hiring ## Hiring

View File

@@ -8,8 +8,8 @@
- [Using Let's Encrypt with NGINX](#using-lets-encrypt-with-nginx) - [Using Let's Encrypt with NGINX](#using-lets-encrypt-with-nginx)
- [Using a self-signed certificate](#using-a-self-signed-certificate) - [Using a self-signed certificate](#using-a-self-signed-certificate)
- [External authentication](#external-authentication) - [External authentication](#external-authentication)
- [HTTPS and self-signed certificates](#https-and-self-signed-certificates) - [HTTPS](#https)
- [Accessing web services](#accessing-web-services) - [Self Signed Certificate](#self-signed-certificate)
- [Using a subdomain](#using-a-subdomain) - [Using a subdomain](#using-a-subdomain)
- [Using a subpath](#using-a-subpath) - [Using a subpath](#using-a-subpath)
- [Stripping `/proxy/<port>` from the request path](#stripping-proxyport-from-the-request-path) - [Stripping `/proxy/<port>` from the request path](#stripping-proxyport-from-the-request-path)
@@ -261,7 +261,7 @@ Google), you can do this with a reverse proxy such as:
- [oauth2_proxy](https://github.com/pusher/oauth2_proxy) - [oauth2_proxy](https://github.com/pusher/oauth2_proxy)
- [Cloudflare Access](https://teams.cloudflare.com/access) - [Cloudflare Access](https://teams.cloudflare.com/access)
## HTTPS and self-signed certificates ## HTTPS
For HTTPS, you can use a self-signed certificate by: For HTTPS, you can use a self-signed certificate by:
@@ -280,9 +280,9 @@ redirect all HTTP requests to HTTPS.
Note: if you set `proxy_set_header Host $host;` in your reverse proxy config, it will change the address displayed in the green section of code-server in the bottom left to show the correct address. Note: if you set `proxy_set_header Host $host;` in your reverse proxy config, it will change the address displayed in the green section of code-server in the bottom left to show the correct address.
## Accessing web services ### Self Signed Certificate
If you're working on web services and want to access it locally, code-server If you're working on a web service and want to access it locally, code-server
can proxy to any port using either a subdomain or a subpath, allowing you to can proxy to any port using either a subdomain or a subpath, allowing you to
securely access these services using code-server's built-in authentication. securely access these services using code-server's built-in authentication.

View File

@@ -15,11 +15,6 @@
- [Raspberry Pi](#raspberry-pi) - [Raspberry Pi](#raspberry-pi)
- [Termux](#termux) - [Termux](#termux)
- [Cloud providers](#cloud-providers) - [Cloud providers](#cloud-providers)
- [Uninstall](#uninstall)
- [install.sh](#installsh-1)
- [Homebrew](#homebrew)
- [yarn, npm](#yarn-npm-1)
- [Debian, Ubuntu](#debian-ubuntu-1)
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -234,7 +229,7 @@ alternative](https://hub.docker.com/r/linuxserver/code-server).
## Helm ## Helm
You can install code-server via [Helm](https://github.com/cdr/code-server/blob/main/ci/helm-chart/README.md). You can install code-server via [Helm](../ci/helm-chart/README.md).
## Raspberry Pi ## Raspberry Pi
@@ -251,54 +246,3 @@ information.
We maintain [one-click apps and install scripts for cloud We maintain [one-click apps and install scripts for cloud
providers](https://github.com/cdr/deploy-code-server) such as DigitalOcean, providers](https://github.com/cdr/deploy-code-server) such as DigitalOcean,
Railway, Heroku, and Azure. Railway, Heroku, and Azure.
## Uninstall
code-server can be completely uninstalled by removing the application directory, and your user configuration directory.
To delete settings and data:
```shell
rm -rf ~/.local/share/code-server ~/.config/code-server
```
### install.sh
If you installed with the install script, by default code-server will be in `~/.local/lib/code-server-<version>` and you can remove it with `rm -rf`. e.g.
```shell
rm -rf ~/.local/lib/code-server-*
```
### Homebrew
To remove the code-server homebrew package, run:
```shell
brew remove code-server
# Alternatively
brew uninstall code-server
```
### yarn, npm
To remove the code-server global module, run:
```shell
yarn global remove code-server
```
or
```shell
npm uninstall -g code-server
```
### Debian, Ubuntu
To uninstall, run:
```shell
sudo apt remove code-server
```

View File

@@ -1,88 +0,0 @@
{
"versions": ["v3.11.1", "v3.11.0"],
"routes": [
{
"title": "Home",
"description": "Learn how to install and run code-server.",
"path": "./README.md",
"icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16px\" xml:space=\"preserve\"><path d=\"M15.45,7L14,5.551V2c0-0.55-0.45-1-1-1h-1c-0.55,0-1,0.45-1,1v0.553L9,0.555C8.727,0.297,8.477,0,8,0S7.273,0.297,7,0.555 L0.55,7C0.238,7.325,0,7.562,0,8c0,0.563,0.432,1,1,1h1v6c0,0.55,0.45,1,1,1h3v-5c0-0.55,0.45-1,1-1h2c0.55,0,1,0.45,1,1v5h3 c0.55,0,1-0.45,1-1V9h1c0.568,0,1-0.437,1-1C16,7.562,15.762,7.325,15.45,7z\"></path></svg>"
},
{
"title": "Requirements",
"description": "Learn about what you need to run code-server.",
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 2V11H2V15C2 16.7 3.3 18 5 18H15C16.7 18 18 16.7 18 15V2H6ZM16 15C16 15.6 15.6 16 15 16H8V4H16V15Z\" /><path d=\"M14 7H10V9H14V7Z\" /><path d=\"M14 11H10V13H14V11Z\" /></svg>",
"path": "./requirements.md"
},
{
"title": "Install",
"description": "How to install code-server.",
"icon": "<svg class=\"MuiSvgIcon-root jss172\" focusable=\"false\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z\"></path></svg>",
"path": "./install.md",
"children": [
{
"title": "npm",
"description": "How to install code-server using npm or yarn",
"path": "./npm.md"
}
]
},
{
"title": "Usage",
"description": "How to set up and use code-server.",
"icon": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 10l-2.5-1.5L15 12V4h5v8z\"></path></svg>",
"path": "./guide.md",
"children": [
{
"title": "iPad",
"description": "How to access your code-server installation using an iPad.",
"path": "./ipad.md"
},
{
"title": "Termux",
"description": "How to install Termux to run code-server on an Android device.",
"path": "./termux.md"
}
]
},
{
"title": "Upgrade",
"description": "How to upgrade code-server.",
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.8049 2.19795C17.7385 2.1311 17.6587 2.07899 17.5708 2.04504C17.4829 2.01108 17.3889 1.99604 17.2948 2.00089C7.89216 2.49153 4.4188 10.8673 4.38528 10.9517C4.33624 11.0736 4.32406 11.2071 4.35028 11.3358C4.3765 11.4645 4.43995 11.5827 4.53274 11.6756L8.32449 15.4674C8.41787 15.5606 8.53669 15.6242 8.66606 15.6502C8.79543 15.6762 8.92959 15.6634 9.05174 15.6135C9.13552 15.5793 17.4664 12.0671 17.9986 2.7087C18.0039 2.61474 17.9895 2.5207 17.9561 2.4327C17.9227 2.3447 17.8712 2.26471 17.8049 2.19795ZM12.3314 9.56427C12.1439 9.75179 11.9051 9.87951 11.645 9.93126C11.385 9.98302 11.1154 9.9565 10.8704 9.85505C10.6254 9.7536 10.4161 9.58178 10.2687 9.36131C10.1214 9.14085 10.0428 8.88166 10.0428 8.6165C10.0428 8.35135 10.1214 8.09215 10.2687 7.87169C10.4161 7.65123 10.6254 7.47941 10.8704 7.37796C11.1154 7.27651 11.385 7.24998 11.645 7.30174C11.9051 7.3535 12.1439 7.48121 12.3314 7.66873C12.5827 7.92012 12.7239 8.26104 12.7239 8.6165C12.7239 8.97197 12.5827 9.31288 12.3314 9.56427Z\"/><path d=\"M2.74602 14.5444C2.92281 14.3664 3.133 14.2251 3.36454 14.1285C3.59608 14.0319 3.8444 13.9819 4.09529 13.9815C4.34617 13.9811 4.59466 14.0302 4.82653 14.126C5.05839 14.2218 5.26907 14.3624 5.44647 14.5398C5.62386 14.7172 5.7645 14.9279 5.86031 15.1598C5.95612 15.3916 6.00522 15.6401 6.00479 15.891C6.00437 16.1419 5.95442 16.3902 5.85782 16.6218C5.76122 16.8533 5.61987 17.0635 5.44186 17.2403C4.69719 17.985 2 18.0004 2 18.0004C2 18.0004 2 15.2884 2.74602 14.5444Z\"/><path d=\"M8.9416 3.48269C7.99688 3.31826 7.02645 3.38371 6.11237 3.67352C5.19828 3.96332 4.36741 4.46894 3.68999 5.14765C3.33153 5.50944 3.01988 5.91477 2.76233 6.35415C2.68692 6.4822 2.6562 6.63169 2.67501 6.77911C2.69381 6.92652 2.76108 7.06351 2.86623 7.16853L4.1994 8.50238C5.43822 6.53634 7.04911 4.83119 8.9416 3.48269Z\"/><path d=\"M16.5181 11.0585C16.6825 12.0033 16.6171 12.9737 16.3273 13.8878C16.0375 14.8019 15.5318 15.6327 14.8531 16.3101C14.4914 16.6686 14.086 16.9803 13.6466 17.2378C13.5186 17.3132 13.3691 17.3439 13.2217 17.3251C13.0743 17.3063 12.9373 17.2391 12.8323 17.1339L11.4984 15.8007C13.4645 14.5619 15.1696 12.951 16.5181 11.0585Z\"/></svg>",
"path": "./upgrade.md"
},
{
"title": "FAQ",
"description": "Frequently asked questions on installing and running code-server.",
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.0001 18.3333C14.6025 18.3333 18.3334 14.6024 18.3334 10C18.3334 5.39762 14.6025 1.66666 10.0001 1.66666C5.39771 1.66666 1.66675 5.39762 1.66675 10C1.66675 14.6024 5.39771 18.3333 10.0001 18.3333Z\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.57495 7.5C7.77087 6.94306 8.15758 6.47342 8.66658 6.17428C9.17558 5.87513 9.77403 5.76578 10.3559 5.86559C10.9378 5.96541 11.4656 6.26794 11.8458 6.71961C12.2261 7.17128 12.4342 7.74294 12.4333 8.33333C12.4333 10 9.93328 10.8333 9.93328 10.8333\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M10 14.1667H10.0083\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>",
"path": "./FAQ.md"
},
{
"title": "Contributing",
"description": "How to contribute to code-server.",
"icon": "<svg width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5 2.5V12.5\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15 7.5C16.3807 7.5 17.5 6.38071 17.5 5C17.5 3.61929 16.3807 2.5 15 2.5C13.6193 2.5 12.5 3.61929 12.5 5C12.5 6.38071 13.6193 7.5 15 7.5Z\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 17.5C6.38071 17.5 7.5 16.3807 7.5 15C7.5 13.6193 6.38071 12.5 5 12.5C3.61929 12.5 2.5 13.6193 2.5 15C2.5 16.3807 3.61929 17.5 5 17.5Z\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15 7.5C15 9.48912 14.2098 11.3968 12.8033 12.8033C11.3968 14.2098 9.48912 15 7.5 15\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>",
"path": "./CONTRIBUTING.md",
"children": [
{
"title": "Code of conduct",
"description": "Coder expects contributors to code-server to behave in a manner that creates an open and welcoming environment.",
"path": "./CODE_OF_CONDUCT.md"
},
{
"title": "Maintenance",
"description": "Learn about the workflow followed by code-server's maintainers.",
"path": "./MAINTAINING.md"
},
{
"title": "Triage",
"description": "How the maintainers triage issues with code-server.",
"path": "./triage.md"
},
{
"title": "Security",
"description": "Learn about the tools used to detect vulnerabilities in code-server, and how you can report vulnerabilities.",
"path": "./SECURITY.md"
}
]
}
]
}

View File

@@ -9,7 +9,7 @@ At the minimum, we recommend:
- 2 CPU cores - 2 CPU cores
You can use any Linux distribution, but [our You can use any Linux distribution, but [our
docs](https://coder.com/docs/code-server/v3.11.1/guide) assume that you're using docs](https://coder.com/docs/code-server/v3.11.0/guide) assume that you're using
Debian hosted by Google Cloud (see the following section for instructions on Debian hosted by Google Cloud (see the following section for instructions on
setting this up). setting this up).

View File

@@ -2,7 +2,7 @@
set -eu set -eu
# code-server's automatic install script. # code-server's automatic install script.
# See https://coder.com/docs/code-server/v3.11.1/install # See https://coder.com/docs/code-server/v3.11.0/install
usage() { usage() {
arg0="$0" arg0="$0"
@@ -66,7 +66,7 @@ fall back to npm so on architectures without pre-built releases this will error.
The installer will cache all downloaded assets into ~/.cache/code-server The installer will cache all downloaded assets into ~/.cache/code-server
More installation docs are at https://coder.com/docs/code-server/v3.11.1/install More installation docs are at https://coder.com/docs/code-server/v3.11.0/install
EOF EOF
} }
@@ -433,7 +433,7 @@ install_npm() {
fi fi
echoerr "Please install npm or yarn to install code-server!" echoerr "Please install npm or yarn to install code-server!"
echoerr "You will need at least node v12 and a few C dependencies." echoerr "You will need at least node v12 and a few C dependencies."
echoerr "See the docs https://coder.com/docs/code-server/v3.11.1/install#yarn-npm" echoerr "See the docs https://coder.com/docs/code-server/v3.11.0/install#yarn-npm"
exit 1 exit 1
} }

View File

@@ -55,12 +55,9 @@ export function asWebviewUri(
}); });
} }
// NOTE@coder: Add the port separately because if the port is in the domain the
// URL will be invalid and the browser will not request it.
const authorityUrl = new URL(`${resource.scheme}://${resource.authority}`);
return URI.from({ return URI.from({
scheme: Schemas.https, scheme: Schemas.https,
authority: `${resource.scheme}+${authorityUrl.hostname}.${webviewRootResourceAuthority}${authorityUrl.port ? (':' + authorityUrl.port) : ''}`, authority: `${resource.scheme}+${resource.authority}.${webviewRootResourceAuthority}`,
path: resource.path, path: resource.path,
fragment: resource.fragment, fragment: resource.fragment,
query: resource.query, query: resource.query,

View File

@@ -256,7 +256,7 @@ async function processResourceRequest(event, requestUrl) {
const firstHostSegment = requestUrl.hostname.slice(0, requestUrl.hostname.length - (resourceBaseAuthority.length + 1)); const firstHostSegment = requestUrl.hostname.slice(0, requestUrl.hostname.length - (resourceBaseAuthority.length + 1));
const scheme = firstHostSegment.split('+', 1)[0]; const scheme = firstHostSegment.split('+', 1)[0];
const authority = firstHostSegment.slice(scheme.length + 1) + requestUrl.port ? (':' + requestUrl.port) : ''; // may be empty const authority = firstHostSegment.slice(scheme.length + 1); // may be empty
for (const parentClient of parentClients) { for (const parentClient of parentClients) {
parentClient.postMessage({ parentClient.postMessage({

View File

@@ -1,7 +1,7 @@
{ {
"name": "code-server", "name": "code-server",
"license": "MIT", "license": "MIT",
"version": "3.11.1", "version": "3.11.0",
"description": "Run VS Code on a remote server.", "description": "Run VS Code on a remote server.",
"homepage": "https://github.com/cdr/code-server", "homepage": "https://github.com/cdr/code-server",
"bugs": { "bugs": {
@@ -57,7 +57,7 @@
"@typescript-eslint/parser": "^4.7.0", "@typescript-eslint/parser": "^4.7.0",
"audit-ci": "^4.0.0", "audit-ci": "^4.0.0",
"browserify": "^17.0.0", "browserify": "^17.0.0",
"codecov": "^3.8.3", "codecov": "^3.8.1",
"doctoc": "^2.0.0", "doctoc": "^2.0.0",
"eslint": "^7.7.0", "eslint": "^7.7.0",
"eslint-config-prettier": "^8.1.0", "eslint-config-prettier": "^8.1.0",
@@ -79,8 +79,7 @@
"postcss": "^8.2.1", "postcss": "^8.2.1",
"browserslist": "^4.16.5", "browserslist": "^4.16.5",
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.1",
"vfile-message": "^2.0.2", "vfile-message": "^2.0.2"
"argon2/@mapbox/node-pre-gyp/tar": "^6.1.3"
}, },
"dependencies": { "dependencies": {
"@coder/logger": "1.1.16", "@coder/logger": "1.1.16",
@@ -95,16 +94,16 @@
"js-yaml": "^4.0.0", "js-yaml": "^4.0.0",
"limiter": "^1.1.5", "limiter": "^1.1.5",
"pem": "^1.14.2", "pem": "^1.14.2",
"proxy-agent": "^5.0.0", "proxy-agent": "^4.0.0",
"proxy-from-env": "^1.1.0", "proxy-from-env": "^1.1.0",
"qs": "6.10.1", "qs": "6.7.0",
"rotating-file-stream": "^2.1.1", "rotating-file-stream": "^2.1.1",
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.1",
"safe-compare": "^1.1.4", "safe-compare": "^1.1.4",
"semver": "^7.1.3", "semver": "^7.1.3",
"split2": "^3.2.2", "split2": "^3.2.2",
"tar-fs": "^2.0.0", "tar-fs": "^2.0.0",
"ws": "^8.0.0", "ws": "^7.2.0",
"xdg-basedir": "^4.0.0", "xdg-basedir": "^4.0.0",
"yarn": "^1.22.4" "yarn": "^1.22.4"
}, },
@@ -149,7 +148,7 @@
], ],
"coverageThreshold": { "coverageThreshold": {
"global": { "global": {
"lines": 60 "lines": 40
} }
}, },
"modulePathIgnorePatterns": [ "modulePathIgnorePatterns": [

View File

@@ -1,18 +0,0 @@
{
"rangeStrategy": "replace",
"extends": ["config:base"],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch", "digest"],
"automerge": true,
"groupName": "Minor dependency updates"
},
{
"matchPaths": ["lib/vscode/"],
"enabled": false
}
],
"vulnerabilityAlerts": {
"enabled": "true"
}
}

View File

@@ -1,8 +1,10 @@
import { getOptions, Options } from "../../common/util" import { getOptions } from "../../common/util"
import "../register" import "../register"
// TODO@jsjoeio: Add proper types. const options = getOptions()
type FixMeLater = any
// TODO: Add proper types.
/* eslint-disable @typescript-eslint/no-explicit-any */
// NOTE@jsjoeio // NOTE@jsjoeio
// This lives here ../../../lib/vscode/src/vs/base/common/platform.ts#L106 // This lives here ../../../lib/vscode/src/vs/base/common/platform.ts#L106
@@ -17,20 +19,7 @@ type NlsConfiguration = {
_resolvedLanguagePackCoreLocation?: string _resolvedLanguagePackCoreLocation?: string
_corruptedFile?: string _corruptedFile?: string
_languagePackSupport?: boolean _languagePackSupport?: boolean
loadBundle?: FixMeLater loadBundle?: any
}
/**
* Helper function to create the path to the bundle
* for getNlsConfiguration.
*/
export function createBundlePath(_resolvedLanguagePackCoreLocation: string, bundle: string) {
// NOTE@jsjoeio - this comment was here before me
// Refers to operating systems that use a different path separator.
// Probably just Windows but we're not sure if "/" breaks on Windows
// so we'll leave it alone for now.
// FIXME: Only works if path separators are /.
return _resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
} }
/** /**
@@ -41,10 +30,14 @@ export function createBundlePath(_resolvedLanguagePackCoreLocation: string, bund
* *
* Make sure to wrap this in a try/catch block when you call it. * Make sure to wrap this in a try/catch block when you call it.
**/ **/
export function getNlsConfiguration(_document: Document, base: string) { export function getNlsConfiguration(document: Document) {
const errorMsgPrefix = "[vscode]" const errorMsgPrefix = "[vscode]"
const nlsConfigElement = _document?.getElementById(nlsConfigElementId) const nlsConfigElement = document?.getElementById(nlsConfigElementId)
const dataSettings = nlsConfigElement?.getAttribute("data-settings") const nlsConfig = nlsConfigElement?.getAttribute("data-settings")
if (!document) {
throw new Error(`${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`)
}
if (!nlsConfigElement) { if (!nlsConfigElement) {
throw new Error( throw new Error(
@@ -52,34 +45,27 @@ export function getNlsConfiguration(_document: Document, base: string) {
) )
} }
if (!dataSettings) { if (!nlsConfig) {
throw new Error( throw new Error(
`${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`, `${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`,
) )
} }
const nlsConfig = JSON.parse(dataSettings) as NlsConfiguration return JSON.parse(nlsConfig) as NlsConfiguration
}
try {
const nlsConfig = getNlsConfiguration(document)
if (nlsConfig._resolvedLanguagePackCoreLocation) { if (nlsConfig._resolvedLanguagePackCoreLocation) {
// NOTE@jsjoeio const bundles = Object.create(null)
// Not sure why we use Object.create(null) instead of {} nlsConfig.loadBundle = (bundle: any, _language: any, cb: any): void => {
// They are not the same
// See: https://stackoverflow.com/a/15518712/3015595
// We copied this from ../../../lib/vscode/src/bootstrap.js#L143
const bundles: {
[key: string]: string
} = Object.create(null)
type LoadBundleCallback = (_: undefined, result?: string) => void
nlsConfig.loadBundle = (bundle: string, _language: string, cb: LoadBundleCallback): void => {
const result = bundles[bundle] const result = bundles[bundle]
if (result) { if (result) {
return cb(undefined, result) return cb(undefined, result)
} }
// FIXME: Only works if path separators are /. // FIXME: Only works if path separators are /.
const path = createBundlePath(nlsConfig._resolvedLanguagePackCoreLocation || "", bundle) const path = nlsConfig._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
fetch(`${base}/vscode/resource/?path=${encodeURIComponent(path)}`) fetch(`${options.base}/vscode/resource/?path=${encodeURIComponent(path)}`)
.then((response) => response.json()) .then((response) => response.json())
.then((json) => { .then((json) => {
bundles[bundle] = json bundles[bundle] = json
@@ -88,61 +74,17 @@ export function getNlsConfiguration(_document: Document, base: string) {
.catch(cb) .catch(cb)
} }
} }
;(self.require as any) = {
return nlsConfig
}
type GetLoaderParams = {
nlsConfig: NlsConfiguration
options: Options
_window: Window
}
/**
* Link to types in the loader source repo
* https://github.com/microsoft/vscode-loader/blob/main/src/loader.d.ts#L280
*/
type Loader = {
baseUrl: string
recordStats: boolean
// TODO@jsjoeio: There don't appear to be any types for trustedTypes yet.
trustedTypesPolicy: FixMeLater
paths: {
[key: string]: string
}
"vs/nls": NlsConfiguration
}
/**
* A helper function which creates a script url if the value
* is valid.
*
* Extracted into a function to make it easier to test
*/
export function _createScriptURL(value: string, origin: string): string {
if (value.startsWith(origin)) {
return value
}
throw new Error(`Invalid script url: ${value}`)
}
/**
* A helper function to get the require loader
*
* This used by VSCode/code-server
* to load files.
*
* We extracted the logic into a function so that
* it's easier to test.
**/
export function getConfigurationForLoader({ nlsConfig, options, _window }: GetLoaderParams) {
const loader: Loader = {
// Without the full URL VS Code will try to load file://. // Without the full URL VS Code will try to load file://.
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`, baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
recordStats: true, recordStats: true,
trustedTypesPolicy: (_window as FixMeLater).trustedTypes?.createPolicy("amdLoader", { // TODO: There don't appear to be any types for trustedTypes yet.
trustedTypesPolicy: (window as any).trustedTypes?.createPolicy("amdLoader", {
createScriptURL(value: string): string { createScriptURL(value: string): string {
return _createScriptURL(value, window.location.origin) if (value.startsWith(window.location.origin)) {
return value
}
throw new Error(`Invalid script url: ${value}`)
}, },
}), }),
paths: { paths: {
@@ -158,16 +100,25 @@ export function getConfigurationForLoader({ nlsConfig, options, _window }: GetLo
}, },
"vs/nls": nlsConfig, "vs/nls": nlsConfig,
} }
} catch (error) {
return loader console.error(error)
/* Probably fine. */
} }
/** export function setBodyBackgroundToThemeBackgroundColor(document: Document, localStorage: Storage) {
* Sets the body background color to match the theme.
*/
export function setBodyBackgroundToThemeBackgroundColor(_document: Document, _localStorage: Storage) {
const errorMsgPrefix = "[vscode]" const errorMsgPrefix = "[vscode]"
const colorThemeData = _localStorage.getItem("colorThemeData")
if (!document) {
throw new Error(`${errorMsgPrefix} Could not set body background to theme background color. Document is undefined.`)
}
if (!localStorage) {
throw new Error(
`${errorMsgPrefix} Could not set body background to theme background color. localStorage is undefined.`,
)
}
const colorThemeData = localStorage.getItem("colorThemeData")
if (!colorThemeData) { if (!colorThemeData) {
throw new Error( throw new Error(
@@ -204,48 +155,14 @@ export function setBodyBackgroundToThemeBackgroundColor(_document: Document, _lo
) )
} }
_document.body.style.background = editorBgColor document.body.style.background = editorBgColor
return null return null
} }
/**
* A helper function to encapsulate all the
* logic used in this file.
*
* We purposely include all of this in a single function
* so that it's easier to test.
*/
export function main(_document: Document | undefined, _window: Window | undefined, _localStorage: Storage | undefined) {
if (!_document) {
throw new Error(`document is undefined.`)
}
if (!_window) {
throw new Error(`window is undefined.`)
}
if (!_localStorage) {
throw new Error(`localStorage is undefined.`)
}
const options = getOptions()
const nlsConfig = getNlsConfiguration(_document, options.base)
const loader = getConfigurationForLoader({
nlsConfig,
options,
_window,
})
;(self.require as unknown as Loader) = loader
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
}
try { try {
main(document, window, localStorage) setBodyBackgroundToThemeBackgroundColor(document, localStorage)
} catch (error) { } catch (error) {
console.error("[vscode] failed to initialize VS Code") console.error("Something went wrong setting the body background to the theme background color.")
console.error(error) console.error(error)
} }

View File

@@ -5,7 +5,7 @@ export async function registerServiceWorker(): Promise<void> {
const options = getOptions() const options = getOptions()
logger.level = options.logLevel logger.level = options.logLevel
const path = normalize(`${options.csStaticBase}/out/browser/serviceWorker.js`) const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`)
try { try {
await navigator.serviceWorker.register(path, { await navigator.serviceWorker.register(path, {
scope: options.base + "/", scope: options.base + "/",

View File

@@ -62,7 +62,7 @@ function newProxyAgent(inVSCode: boolean): http.Agent {
// If they have $NO_PROXY set to example.com then this check won't work! // If they have $NO_PROXY set to example.com then this check won't work!
// But that's drastically unlikely. // But that's drastically unlikely.
export function shouldEnableProxy(): boolean { function shouldEnableProxy(): boolean {
let shouldEnable = false let shouldEnable = false
const httpProxy = proxyFromEnv.getProxyForUrl(`http://example.com`) const httpProxy = proxyFromEnv.getProxyForUrl(`http://example.com`)

View File

@@ -63,10 +63,9 @@ router.get("/", async (req, res) => {
* TODO: Might currently be unused. * TODO: Might currently be unused.
*/ */
router.get("/resource(/*)?", ensureAuthenticated, async (req, res) => { router.get("/resource(/*)?", ensureAuthenticated, async (req, res) => {
const path = getFirstString(req.query.path) if (typeof req.query.path === "string") {
if (path) { res.set("Content-Type", getMediaMime(req.query.path))
res.set("Content-Type", getMediaMime(path)) res.send(await fs.readFile(pathToFsPath(req.query.path)))
res.send(await fs.readFile(pathToFsPath(path)))
} }
}) })
@@ -74,10 +73,9 @@ router.get("/resource(/*)?", ensureAuthenticated, async (req, res) => {
* Used by VS Code to load files. * Used by VS Code to load files.
*/ */
router.get("/vscode-remote-resource(/*)?", ensureAuthenticated, async (req, res) => { router.get("/vscode-remote-resource(/*)?", ensureAuthenticated, async (req, res) => {
const path = getFirstString(req.query.path) if (typeof req.query.path === "string") {
if (path) { res.set("Content-Type", getMediaMime(req.query.path))
res.set("Content-Type", getMediaMime(path)) res.send(await fs.readFile(pathToFsPath(req.query.path)))
res.send(await fs.readFile(pathToFsPath(path)))
} }
}) })

View File

@@ -458,11 +458,17 @@ enum CharCode {
* Taken from vs/base/common/uri.ts. It's not imported to avoid also importing * Taken from vs/base/common/uri.ts. It's not imported to avoid also importing
* everything that file imports. * everything that file imports.
*/ */
export function pathToFsPath(path: string, keepDriveLetterCasing = false): string { export function pathToFsPath(path: string | string[], keepDriveLetterCasing = false): string {
const isWindows = process.platform === "win32" const isWindows = process.platform === "win32"
const uri = { authority: undefined, path: getFirstString(path) || "", scheme: "file" } const uri = { authority: undefined, path: getFirstString(path), scheme: "file" }
let value: string let value: string
if (typeof uri.path !== "string") {
throw new Error(
`Could not compute fsPath from given uri. Expected path to be of type string, but was of type ${typeof uri.path}.`,
)
}
if (uri.authority && uri.path.length > 1 && uri.scheme === "file") { if (uri.authority && uri.path.length > 1 && uri.scheme === "file") {
// unc path: file://shares/c$/far/boo // unc path: file://shares/c$/far/boo
value = `//${uri.authority}${uri.path}` value = `//${uri.authority}${uri.path}`

View File

@@ -16,8 +16,5 @@
"ts-jest": "^26.4.4", "ts-jest": "^26.4.4",
"@types/wtfnode": "^0.7.0", "@types/wtfnode": "^0.7.0",
"wtfnode": "^0.9.0" "wtfnode": "^0.9.0"
},
"resolutions": {
"argon2/@mapbox/node-pre-gyp/tar": "^6.1.3"
} }
} }

View File

@@ -1,5 +1,5 @@
import { JSDOM } from "jsdom" import { JSDOM } from "jsdom"
import { LocationLike } from "../../common/util.test" import { LocationLike } from "../../util.test"
describe("login", () => { describe("login", () => {
describe("there is an element with id 'base'", () => { describe("there is an element with id 'base'", () => {

View File

@@ -5,47 +5,48 @@ import { JSDOM } from "jsdom"
import { import {
getNlsConfiguration, getNlsConfiguration,
nlsConfigElementId, nlsConfigElementId,
getConfigurationForLoader,
setBodyBackgroundToThemeBackgroundColor, setBodyBackgroundToThemeBackgroundColor,
_createScriptURL,
main,
createBundlePath,
} from "../../../../src/browser/pages/vscode" } from "../../../../src/browser/pages/vscode"
describe("vscode", () => { describe("vscode", () => {
describe("getNlsConfiguration", () => { describe("getNlsConfiguration", () => {
let _document: Document
beforeEach(() => { beforeEach(() => {
// We use underscores to not confuse with global values const { window } = new JSDOM()
const { window: _window } = new JSDOM() global.document = window.document
_document = _window.document
}) })
it("should throw an error if Document is undefined", () => {
const errorMsgPrefix = "[vscode]"
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`
expect(() => {
getNlsConfiguration(undefined as any as Document)
}).toThrowError(errorMessage)
})
it("should throw an error if no nlsConfigElement", () => { it("should throw an error if no nlsConfigElement", () => {
const errorMsgPrefix = "[vscode]" const errorMsgPrefix = "[vscode]"
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}` const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}`
expect(() => { expect(() => {
getNlsConfiguration(_document, "") getNlsConfiguration(document)
}).toThrowError(errorMessage) }).toThrowError(errorMessage)
}) })
it("should throw an error if no nlsConfig", () => { it("should throw an error if no nlsConfig", () => {
const mockElement = _document.createElement("div") const mockElement = document.createElement("div")
mockElement.setAttribute("id", nlsConfigElementId) mockElement.setAttribute("id", nlsConfigElementId)
_document.body.appendChild(mockElement) document.body.appendChild(mockElement)
const errorMsgPrefix = "[vscode]" const errorMsgPrefix = "[vscode]"
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.` const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`
expect(() => { expect(() => {
getNlsConfiguration(_document, "") getNlsConfiguration(document)
}).toThrowError(errorMessage) }).toThrowError(errorMessage)
_document.body.removeChild(mockElement) document.body.removeChild(mockElement)
}) })
it("should return the correct configuration", () => { it("should return the correct configuration", () => {
const mockElement = _document.createElement("div") const mockElement = document.createElement("div")
const dataSettings = { const dataSettings = {
first: "Jane", first: "Jane",
last: "Doe", last: "Doe",
@@ -53,52 +54,22 @@ describe("vscode", () => {
mockElement.setAttribute("id", nlsConfigElementId) mockElement.setAttribute("id", nlsConfigElementId)
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings)) mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
_document.body.appendChild(mockElement) document.body.appendChild(mockElement)
const actual = getNlsConfiguration(_document, "") const actual = getNlsConfiguration(global.document)
expect(actual).toStrictEqual(dataSettings) expect(actual).toStrictEqual(dataSettings)
_document.body.removeChild(mockElement) document.body.removeChild(mockElement)
})
it("should return have loadBundle property if _resolvedLangaugePackCoreLocation", () => {
const mockElement = _document.createElement("div")
const dataSettings = {
locale: "en",
availableLanguages: ["en", "de"],
_resolvedLanguagePackCoreLocation: "./",
}
mockElement.setAttribute("id", nlsConfigElementId)
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
_document.body.appendChild(mockElement)
const nlsConfig = getNlsConfiguration(_document, "")
expect(nlsConfig._resolvedLanguagePackCoreLocation).not.toBe(undefined)
expect(nlsConfig.loadBundle).not.toBe(undefined)
_document.body.removeChild(mockElement)
})
})
describe("createBundlePath", () => {
it("should return the correct path", () => {
const _resolvedLangaugePackCoreLocation = "./languages"
const bundle = "/bundle.js"
const expected = "./languages/!bundle.js.nls.json"
const actual = createBundlePath(_resolvedLangaugePackCoreLocation, bundle)
expect(actual).toBe(expected)
}) })
}) })
describe("setBodyBackgroundToThemeBackgroundColor", () => { describe("setBodyBackgroundToThemeBackgroundColor", () => {
let _document: Document
let _localStorage: Storage
beforeEach(() => { beforeEach(() => {
// We need to set the url in the JSDOM constructor // We need to set the url in the JSDOM constructor
// to prevent this error "SecurityError: localStorage is not available for opaque origins" // to prevent this error "SecurityError: localStorage is not available for opaque origins"
// See: https://github.com/jsdom/jsdom/issues/2304#issuecomment-622314949 // See: https://github.com/jsdom/jsdom/issues/2304#issuecomment-622314949
const { window: _window } = new JSDOM("", { url: "http://localhost" }) const { window } = new JSDOM("", { url: "http://localhost" })
_document = _window.document global.document = window.document
_localStorage = _window.localStorage global.localStorage = window.localStorage
}) })
it("should return null", () => { it("should return null", () => {
const test = { const test = {
@@ -106,31 +77,49 @@ describe("vscode", () => {
[`editor.background`]: "#ff3270", [`editor.background`]: "#ff3270",
}, },
} }
_localStorage.setItem("colorThemeData", JSON.stringify(test)) localStorage.setItem("colorThemeData", JSON.stringify(test))
expect(setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)).toBeNull() expect(setBodyBackgroundToThemeBackgroundColor(document, localStorage)).toBeNull()
_localStorage.removeItem("colorThemeData") localStorage.removeItem("colorThemeData")
})
it("should throw an error if Document is undefined", () => {
const errorMsgPrefix = "[vscode]"
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Document is undefined.`
expect(() => {
// @ts-expect-error We need to test when document is undefined
setBodyBackgroundToThemeBackgroundColor(undefined, localStorage)
}).toThrowError(errorMessage)
})
it("should throw an error if localStorage is undefined", () => {
const errorMsgPrefix = "[vscode]"
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. localStorage is undefined.`
expect(() => {
// @ts-expect-error We need to test when localStorage is undefined
setBodyBackgroundToThemeBackgroundColor(document, undefined)
}).toThrowError(errorMessage)
}) })
it("should throw an error if it can't find colorThemeData in localStorage", () => { it("should throw an error if it can't find colorThemeData in localStorage", () => {
const errorMsgPrefix = "[vscode]" const errorMsgPrefix = "[vscode]"
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not find colorThemeData in localStorage.` const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not find colorThemeData in localStorage.`
expect(() => { expect(() => {
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage) setBodyBackgroundToThemeBackgroundColor(document, localStorage)
}).toThrowError(errorMessage) }).toThrowError(errorMessage)
}) })
it("should throw an error if there is an error parsing colorThemeData from localStorage", () => { it("should throw an error if there is an error parsing colorThemeData from localStorage", () => {
const errorMsgPrefix = "[vscode]" const errorMsgPrefix = "[vscode]"
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not parse colorThemeData from localStorage.` const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not parse colorThemeData from localStorage.`
_localStorage.setItem( localStorage.setItem(
"colorThemeData", "colorThemeData",
'{"id":"vs-dark max-SS-Cyberpunk-themes-cyberpunk-umbra-color-theme-json","label":"Activate UMBRA protocol","settingsId":"Activate "errorForeground":"#ff3270","foreground":"#ffffff","sideBarTitle.foreground":"#bbbbbb"},"watch\\":::false}', '{"id":"vs-dark max-SS-Cyberpunk-themes-cyberpunk-umbra-color-theme-json","label":"Activate UMBRA protocol","settingsId":"Activate "errorForeground":"#ff3270","foreground":"#ffffff","sideBarTitle.foreground":"#bbbbbb"},"watch\\":::false}',
) )
expect(() => { expect(() => {
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage) setBodyBackgroundToThemeBackgroundColor(document, localStorage)
}).toThrowError(errorMessage) }).toThrowError(errorMessage)
localStorage.removeItem("colorThemeData") localStorage.removeItem("colorThemeData")
@@ -142,13 +131,13 @@ describe("vscode", () => {
const test = { const test = {
id: "hey-joe", id: "hey-joe",
} }
_localStorage.setItem("colorThemeData", JSON.stringify(test)) localStorage.setItem("colorThemeData", JSON.stringify(test))
expect(() => { expect(() => {
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage) setBodyBackgroundToThemeBackgroundColor(document, localStorage)
}).toThrowError(errorMessage) }).toThrowError(errorMessage)
_localStorage.removeItem("colorThemeData") localStorage.removeItem("colorThemeData")
}) })
it("should throw an error if there is no editor.background color", () => { it("should throw an error if there is no editor.background color", () => {
const errorMsgPrefix = "[vscode]" const errorMsgPrefix = "[vscode]"
@@ -160,13 +149,13 @@ describe("vscode", () => {
editor: "#fff", editor: "#fff",
}, },
} }
_localStorage.setItem("colorThemeData", JSON.stringify(test)) localStorage.setItem("colorThemeData", JSON.stringify(test))
expect(() => { expect(() => {
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage) setBodyBackgroundToThemeBackgroundColor(document, localStorage)
}).toThrowError(errorMessage) }).toThrowError(errorMessage)
_localStorage.removeItem("colorThemeData") localStorage.removeItem("colorThemeData")
}) })
it("should set the body background to the editor background color", () => { it("should set the body background to the editor background color", () => {
const test = { const test = {
@@ -174,188 +163,16 @@ describe("vscode", () => {
[`editor.background`]: "#ff3270", [`editor.background`]: "#ff3270",
}, },
} }
_localStorage.setItem("colorThemeData", JSON.stringify(test)) localStorage.setItem("colorThemeData", JSON.stringify(test))
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage) setBodyBackgroundToThemeBackgroundColor(document, localStorage)
// When the body.style.backgroundColor is set using hex // When the body.style.backgroundColor is set using hex
// it is converted to rgb // it is converted to rgb
// which is why we use that in the assertion // which is why we use that in the assertion
expect(_document.body.style.backgroundColor).toBe("rgb(255, 50, 112)") expect(document.body.style.backgroundColor).toBe("rgb(255, 50, 112)")
_localStorage.removeItem("colorThemeData") localStorage.removeItem("colorThemeData")
})
})
describe("getConfigurationForLoader", () => {
let _window: Window
beforeEach(() => {
const { window: __window } = new JSDOM()
// @ts-expect-error the Window from JSDOM is not exactly the same as Window
// so we expect an error here
_window = __window
})
it("should return a loader object (with undefined trustedTypesPolicy)", () => {
const options = {
base: ".",
csStaticBase: "/",
logLevel: 1,
}
const nlsConfig = {
first: "Jane",
last: "Doe",
locale: "en",
availableLanguages: {},
}
const loader = getConfigurationForLoader({
options,
_window,
nlsConfig: nlsConfig,
})
expect(loader).toStrictEqual({
baseUrl: "http://localhost//lib/vscode/out",
paths: {
"iconv-lite-umd": "../node_modules/iconv-lite-umd/lib/iconv-lite-umd.js",
jschardet: "../node_modules/jschardet/dist/jschardet.min.js",
"tas-client-umd": "../node_modules/tas-client-umd/lib/tas-client-umd.js",
"vscode-oniguruma": "../node_modules/vscode-oniguruma/release/main",
"vscode-textmate": "../node_modules/vscode-textmate/release/main",
xterm: "../node_modules/xterm/lib/xterm.js",
"xterm-addon-search": "../node_modules/xterm-addon-search/lib/xterm-addon-search.js",
"xterm-addon-unicode11": "../node_modules/xterm-addon-unicode11/lib/xterm-addon-unicode11.js",
"xterm-addon-webgl": "../node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js",
},
recordStats: true,
// TODO@jsjoeio address trustedTypesPolicy part
// might need to look up types
// and find a way to test the function
// maybe extract function into function
// and test manually
trustedTypesPolicy: undefined,
"vs/nls": {
availableLanguages: {},
first: "Jane",
last: "Doe",
locale: "en",
},
})
})
it("should return a loader object with trustedTypesPolicy", () => {
interface PolicyOptions {
createScriptUrl: (url: string) => string
}
function mockCreatePolicy(policyName: string, options: PolicyOptions) {
return {
name: policyName,
...options,
}
}
const mockFn = jest.fn(mockCreatePolicy)
// @ts-expect-error we are adding a custom property to window
_window.trustedTypes = {
createPolicy: mockFn,
}
const options = {
base: "/",
csStaticBase: "/",
logLevel: 1,
}
const nlsConfig = {
first: "Jane",
last: "Doe",
locale: "en",
availableLanguages: {},
}
const loader = getConfigurationForLoader({
options,
_window,
nlsConfig: nlsConfig,
})
expect(loader.trustedTypesPolicy).not.toBe(undefined)
expect(loader.trustedTypesPolicy.name).toBe("amdLoader")
})
})
describe("_createScriptURL", () => {
it("should return the correct url", () => {
const url = _createScriptURL("localhost/foo/bar.js", "localhost")
expect(url).toBe("localhost/foo/bar.js")
})
it("should throw if the value doesn't start with the origin", () => {
expect(() => {
_createScriptURL("localhost/foo/bar.js", "coder.com")
}).toThrow("Invalid script url: localhost/foo/bar.js")
})
})
describe("main", () => {
let _window: Window
let _document: Document
let _localStorage: Storage
beforeEach(() => {
// We need to set the url in the JSDOM constructor
// to prevent this error "SecurityError: localStorage is not available for opaque origins"
// See: https://github.com/jsdom/jsdom/issues/2304#issuecomment-62231494
const { window: __window } = new JSDOM("", { url: "http://localhost" })
// @ts-expect-error the Window from JSDOM is not exactly the same as Window
// so we expect an error here
_window = __window
_document = __window.document
_localStorage = __window.localStorage
const mockElement = _document.createElement("div")
const dataSettings = {
first: "Jane",
last: "Doe",
}
mockElement.setAttribute("id", nlsConfigElementId)
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
_document.body.appendChild(mockElement)
const test = {
colorMap: {
[`editor.background`]: "#ff3270",
},
}
_localStorage.setItem("colorThemeData", JSON.stringify(test))
})
afterEach(() => {
_localStorage.removeItem("colorThemeData")
})
it("should throw if document is missing", () => {
expect(() => {
main(undefined, _window, _localStorage)
}).toThrow("document is undefined.")
})
it("should throw if window is missing", () => {
expect(() => {
main(_document, undefined, _localStorage)
}).toThrow("window is undefined.")
})
it("should throw if localStorage is missing", () => {
expect(() => {
main(_document, _window, undefined)
}).toThrow("localStorage is undefined.")
})
it("should add loader to self.require", () => {
main(_document, _window, _localStorage)
expect(Object.prototype.hasOwnProperty.call(self, "require")).toBe(true)
})
it("should not throw in browser context", () => {
// Assuming we call it in a normal browser context
// where everything is defined
expect(() => {
main(_document, _window, _localStorage)
}).not.toThrow()
}) })
}) })
}) })

View File

@@ -1,7 +1,7 @@
import { JSDOM } from "jsdom" import { JSDOM } from "jsdom"
import { registerServiceWorker } from "../../../src/browser/register" import { registerServiceWorker } from "../../../src/browser/register"
import { createLoggerMock } from "../../utils/helpers" import { createLoggerMock } from "../../utils/helpers"
import { LocationLike } from "../common/util.test" import { LocationLike } from "../util.test"
describe("register", () => { describe("register", () => {
describe("when navigator and serviceWorker are defined", () => { describe("when navigator and serviceWorker are defined", () => {
@@ -155,7 +155,7 @@ describe("register", () => {
await registerServiceWorker() await registerServiceWorker()
expect(mockFn).toBeCalled() expect(mockFn).toBeCalled()
expect(serviceWorkerPath).toMatch(`${csStaticBasePath}/out/browser/serviceWorker.js`) expect(serviceWorkerPath).toMatch(`${csStaticBasePath}/dist/serviceWorker.js`)
expect(serviceWorkerScope).toMatch("/") expect(serviceWorkerScope).toMatch("/")
}) })
it("should register when options.base is defined", async () => { it("should register when options.base is defined", async () => {
@@ -176,7 +176,7 @@ describe("register", () => {
await registerServiceWorker() await registerServiceWorker()
expect(mockFn).toBeCalled() expect(mockFn).toBeCalled()
expect(serviceWorkerPath).toMatch(`/out/browser/serviceWorker.js`) expect(serviceWorkerPath).toMatch(`/dist/serviceWorker.js`)
expect(serviceWorkerScope).toMatch("/") expect(serviceWorkerScope).toMatch("/")
}) })
}) })

View File

@@ -3,9 +3,9 @@ import { promises as fs } from "fs"
import * as net from "net" import * as net from "net"
import * as os from "os" import * as os from "os"
import * as path from "path" import * as path from "path"
import { Args, parse, setDefaults, shouldOpenInExistingInstance, splitOnFirstEquals } from "../../../src/node/cli" import { Args, parse, setDefaults, shouldOpenInExistingInstance, splitOnFirstEquals } from "../../src/node/cli"
import { tmpdir } from "../../../src/node/constants" import { tmpdir } from "../../src/node/constants"
import { paths } from "../../../src/node/util" import { paths } from "../../src/node/util"
type Mutable<T> = { type Mutable<T> = {
-readonly [P in keyof T]: T[P] -readonly [P in keyof T]: T[P]

View File

@@ -1,7 +1,7 @@
import { createLoggerMock } from "../../utils/helpers" import { createLoggerMock } from "../utils/helpers"
describe("constants", () => { describe("constants", () => {
let constants: typeof import("../../../src/node/constants") let constants: typeof import("../../src/node/constants")
describe("with package.json defined", () => { describe("with package.json defined", () => {
const loggerModule = createLoggerMock() const loggerModule = createLoggerMock()
@@ -15,8 +15,8 @@ describe("constants", () => {
beforeAll(() => { beforeAll(() => {
jest.mock("@coder/logger", () => loggerModule) jest.mock("@coder/logger", () => loggerModule)
jest.mock("../../../package.json", () => mockPackageJson, { virtual: true }) jest.mock("../../package.json", () => mockPackageJson, { virtual: true })
constants = require("../../../src/node/constants") constants = require("../../src/node/constants")
}) })
afterAll(() => { afterAll(() => {
@@ -57,8 +57,8 @@ describe("constants", () => {
} }
beforeAll(() => { beforeAll(() => {
jest.mock("../../../package.json", () => mockPackageJson, { virtual: true }) jest.mock("../../package.json", () => mockPackageJson, { virtual: true })
constants = require("../../../src/node/constants") constants = require("../../src/node/constants")
}) })
afterAll(() => { afterAll(() => {

View File

@@ -1,8 +1,8 @@
// Note: we need to import logger from the root // Note: we need to import logger from the root
// because this is the logger used in logError in ../src/common/util // because this is the logger used in logError in ../src/common/util
import { logger } from "@coder/logger" import { logger } from "../../node_modules/@coder/logger"
import { Emitter } from "../../../src/common/emitter" import { Emitter } from "../../src/common/emitter"
describe("emitter", () => { describe("emitter", () => {
let spy: jest.SpyInstance let spy: jest.SpyInstance

View File

@@ -1,5 +1,5 @@
import { promises as fs } from "fs" import { promises as fs } from "fs"
import { getAvailablePort, tmpdir, useEnv } from "../../test/utils/helpers" import { tmpdir } from "../../test/utils/helpers"
/** /**
* This file is for testing test helpers (not core code). * This file is for testing test helpers (not core code).
@@ -12,43 +12,3 @@ describe("test helpers", () => {
expect(fs.access(pathToTempDir)).resolves.toStrictEqual(undefined) expect(fs.access(pathToTempDir)).resolves.toStrictEqual(undefined)
}) })
}) })
describe("useEnv", () => {
beforeAll(() => {
jest.resetModules()
process.env.TEST_USE_ENV = "test environment variable"
})
afterAll(() => {
delete process.env.TEST_USE_ENV
})
it("should set and reset the env var", () => {
const envKey = "TEST_ENV_VAR"
const [setValue, resetValue] = useEnv(envKey)
setValue("hello-world")
expect(process.env[envKey]).toEqual("hello-world")
resetValue()
expect(process.env[envKey]).toEqual(undefined)
})
it("should set and reset the env var where a value was already set", () => {
const envKey = "TEST_USE_ENV"
expect(process.env[envKey]).toEqual("test environment variable")
const [setValue, resetValue] = useEnv(envKey)
setValue("hello there")
expect(process.env[envKey]).toEqual("hello there")
resetValue()
expect(process.env[envKey]).toEqual("test environment variable")
})
})
describe("getAvailablePort", () => {
it("should return a valid port", async () => {
const port = await getAvailablePort()
expect(port).toBeGreaterThan(0)
expect(port).toBeLessThanOrEqual(65535)
})
it("should return different ports for different calls", async () => {
const portOne = await getAvailablePort()
const portTwo = await getAvailablePort()
expect(portOne).not.toEqual(portTwo)
})
})

View File

@@ -1,4 +1,4 @@
import { HttpCode, HttpError } from "../../../src/common/http" import { HttpCode, HttpError } from "../../src/common/http"
describe("http", () => { describe("http", () => {
describe("HttpCode", () => { describe("HttpCode", () => {

View File

@@ -1,215 +0,0 @@
import bodyParser from "body-parser"
import * as express from "express"
import * as nodeFetch from "node-fetch"
import * as http from "http"
import { HttpCode } from "../../../src/common/http"
import { proxy } from "../../../src/node/proxy"
import * as httpserver from "../../utils/httpserver"
import * as integration from "../../utils/integration"
import { getAvailablePort } from "../../utils/helpers"
describe("proxy", () => {
const nhooyrDevServer = new httpserver.HttpServer()
let codeServer: httpserver.HttpServer | undefined
let proxyPath: string
let absProxyPath: string
let e: express.Express
beforeAll(async () => {
await nhooyrDevServer.listen((req, res) => {
e(req, res)
})
proxyPath = `/proxy/${nhooyrDevServer.port()}/wsup`
absProxyPath = proxyPath.replace("/proxy/", "/absproxy/")
})
afterAll(async () => {
await nhooyrDevServer.close()
})
beforeEach(() => {
e = express.default()
})
afterEach(async () => {
if (codeServer) {
await codeServer.close()
codeServer = undefined
}
})
it("should rewrite the base path", async () => {
e.get("/wsup", (req, res) => {
res.json("asher is the best")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath)
expect(resp.status).toBe(200)
const json = await resp.json()
expect(json).toBe("asher is the best")
})
it("should not rewrite the base path", async () => {
e.get(absProxyPath, (req, res) => {
res.json("joe is the best")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(absProxyPath)
expect(resp.status).toBe(200)
const json = await resp.json()
expect(json).toBe("joe is the best")
})
it("should rewrite redirects", async () => {
e.post("/wsup", (req, res) => {
res.redirect(307, "/finale")
})
e.post("/finale", (req, res) => {
res.json("redirect success")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath, {
method: "POST",
})
expect(resp.status).toBe(200)
expect(await resp.json()).toBe("redirect success")
})
it("should not rewrite redirects", async () => {
const finalePath = absProxyPath.replace("/wsup", "/finale")
e.post(absProxyPath, (req, res) => {
res.redirect(307, finalePath)
})
e.post(finalePath, (req, res) => {
res.json("redirect success")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(absProxyPath, {
method: "POST",
})
expect(resp.status).toBe(200)
expect(await resp.json()).toBe("redirect success")
})
it("should allow post bodies", async () => {
e.use(bodyParser.json({ strict: false }))
e.post("/wsup", (req, res) => {
res.json(req.body)
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath, {
method: "post",
body: JSON.stringify("coder is the best"),
headers: {
"Content-Type": "application/json",
},
})
expect(resp.status).toBe(200)
expect(await resp.json()).toBe("coder is the best")
})
it("should handle bad requests", async () => {
e.use(bodyParser.json({ strict: false }))
e.post("/wsup", (req, res) => {
res.json(req.body)
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath, {
method: "post",
body: "coder is the best",
headers: {
"Content-Type": "application/json",
},
})
expect(resp.status).toBe(400)
expect(resp.statusText).toMatch("Bad Request")
})
it("should handle invalid routes", async () => {
e.post("/wsup", (req, res) => {
res.json(req.body)
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(`${proxyPath}/hello`)
expect(resp.status).toBe(404)
expect(resp.statusText).toMatch("Not Found")
})
it("should handle errors", async () => {
e.use(bodyParser.json({ strict: false }))
e.post("/wsup", (req, res) => {
throw new Error("BROKEN")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath, {
method: "post",
body: JSON.stringify("coder is the best"),
headers: {
"Content-Type": "application/json",
},
})
expect(resp.status).toBe(500)
expect(resp.statusText).toMatch("Internal Server Error")
})
})
// NOTE@jsjoeio
// Both this test suite and the one above it are very similar
// The main difference is this one uses http and node-fetch
// and specifically tests the proxy in isolation vs. using
// the httpserver abstraction we've built.
//
// Leaving this as a separate test suite for now because
// we may consider refactoring the httpserver abstraction
// in the future.
//
// If you're writing a test specifically for code in
// src/node/proxy.ts, you should probably add it to
// this test suite.
describe("proxy (standalone)", () => {
let URL = ""
let PROXY_URL = ""
let testServer: http.Server
let proxyTarget: http.Server
beforeEach(async () => {
const PORT = await getAvailablePort()
const PROXY_PORT = await getAvailablePort()
URL = `http://localhost:${PORT}`
PROXY_URL = `http://localhost:${PROXY_PORT}`
// Define server and a proxy server
testServer = http.createServer((req, res) => {
proxy.web(req, res, {
target: PROXY_URL,
})
})
proxyTarget = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" })
res.end()
})
// Start both servers
await proxyTarget.listen(PROXY_PORT)
await testServer.listen(PORT)
})
afterEach(async () => {
await testServer.close()
await proxyTarget.close()
})
it("should return a 500 when proxy target errors ", async () => {
// Close the proxy target so that proxy errors
await proxyTarget.close()
const errorResp = await nodeFetch.default(`${URL}/error`)
expect(errorResp.status).toBe(HttpCode.ServerError)
expect(errorResp.statusText).toBe("Internal Server Error")
})
it("should proxy correctly", async () => {
const resp = await nodeFetch.default(`${URL}/route`)
expect(resp.status).toBe(200)
expect(resp.statusText).toBe("OK")
})
})

View File

@@ -1,39 +0,0 @@
import { shouldEnableProxy } from "../../../src/node/proxy_agent"
import { useEnv } from "../../utils/helpers"
describe("shouldEnableProxy", () => {
const [setHTTPProxy, resetHTTPProxy] = useEnv("HTTP_PROXY")
const [setHTTPSProxy, resetHTTPSProxy] = useEnv("HTTPS_PROXY")
const [setNoProxy, resetNoProxy] = useEnv("NO_PROXY")
beforeEach(() => {
jest.resetModules() // Most important - it clears the cache
resetHTTPProxy()
resetNoProxy()
resetHTTPSProxy()
})
it("returns true when HTTP_PROXY is set", () => {
setHTTPProxy("http://proxy.example.com")
expect(shouldEnableProxy()).toBe(true)
})
it("returns true when HTTPS_PROXY is set", () => {
setHTTPSProxy("https://proxy.example.com")
expect(shouldEnableProxy()).toBe(true)
})
it("returns false when NO_PROXY is set", () => {
setNoProxy("*")
expect(shouldEnableProxy()).toBe(false)
})
it("should return false when neither HTTP_PROXY nor HTTPS_PROXY is set", () => {
expect(shouldEnableProxy()).toBe(false)
})
it("should return false when NO_PROXY is set to https://example.com", () => {
setNoProxy("https://example.com")
expect(shouldEnableProxy()).toBe(false)
})
it("should return false when NO_PROXY is set to http://example.com", () => {
setNoProxy("http://example.com")
expect(shouldEnableProxy()).toBe(false)
})
})

View File

@@ -1,8 +1,5 @@
import * as cp from "child_process" import * as cp from "child_process"
import { promises as fs } from "fs"
import * as path from "path"
import { generateUuid } from "../../../src/common/util" import { generateUuid } from "../../../src/common/util"
import { tmpdir } from "../../../src/node/constants"
import * as util from "../../../src/node/util" import * as util from "../../../src/node/util"
describe("getEnvPaths", () => { describe("getEnvPaths", () => {
@@ -467,8 +464,22 @@ describe("pathToFsPath", () => {
it("should keep drive letter casing when set to true", () => { it("should keep drive letter casing when set to true", () => {
expect(util.pathToFsPath("/C:/far/bo", true)).toBe("C:/far/bo") expect(util.pathToFsPath("/C:/far/bo", true)).toBe("C:/far/bo")
}) })
it("should throw an error if a non-string is passed in for path", () => {
expect(() =>
util
// @ts-expect-error We need to check other types
.pathToFsPath({}),
).toThrow(`Could not compute fsPath from given uri. Expected path to be of type string, but was of type undefined.`)
})
it("should not throw an error for a string array", () => {
// @ts-expect-error We need to check other types
expect(() => util.pathToFsPath(["/hello/foo", "/hello/bar"]).not.toThrow())
})
it("should use the first string in a string array", () => {
expect(util.pathToFsPath(["/hello/foo", "/hello/bar"])).toBe("/hello/foo")
})
it("should replace / with \\ on Windows", () => { it("should replace / with \\ on Windows", () => {
const ORIGINAL_PLATFORM = process.platform let ORIGINAL_PLATFORM = process.platform
Object.defineProperty(process, "platform", { Object.defineProperty(process, "platform", {
value: "win32", value: "win32",
@@ -481,23 +492,3 @@ describe("pathToFsPath", () => {
}) })
}) })
}) })
describe("isFile", () => {
const testDir = path.join(tmpdir, "tests", "isFile")
let pathToFile = ""
beforeEach(async () => {
pathToFile = path.join(testDir, "foo.txt")
await fs.mkdir(testDir, { recursive: true })
await fs.writeFile(pathToFile, "hello")
})
afterEach(async () => {
await fs.rm(testDir, { recursive: true, force: true })
})
it("should return false if the path doesn't exist", async () => {
expect(await util.isFile(testDir)).toBe(false)
})
it("should return true if is file", async () => {
expect(await util.isFile(pathToFile)).toBe(true)
})
})

View File

@@ -2,11 +2,11 @@ import { logger } from "@coder/logger"
import * as express from "express" import * as express from "express"
import * as fs from "fs" import * as fs from "fs"
import * as path from "path" import * as path from "path"
import { HttpCode } from "../../../src/common/http" import { HttpCode } from "../../src/common/http"
import { AuthType } from "../../../src/node/cli" import { AuthType } from "../../src/node/cli"
import { codeServer, PluginAPI } from "../../../src/node/plugin" import { codeServer, PluginAPI } from "../../src/node/plugin"
import * as apps from "../../../src/node/routes/apps" import * as apps from "../../src/node/routes/apps"
import * as httpserver from "../../utils/httpserver" import * as httpserver from "../utils/httpserver"
const fsp = fs.promises const fsp = fs.promises
// Jest overrides `require` so our usual override doesn't work. // Jest overrides `require` so our usual override doesn't work.

105
test/unit/proxy.test.ts Normal file
View File

@@ -0,0 +1,105 @@
import bodyParser from "body-parser"
import * as express from "express"
import * as httpserver from "../utils/httpserver"
import * as integration from "../utils/integration"
describe("proxy", () => {
const nhooyrDevServer = new httpserver.HttpServer()
let codeServer: httpserver.HttpServer | undefined
let proxyPath: string
let absProxyPath: string
let e: express.Express
beforeAll(async () => {
await nhooyrDevServer.listen((req, res) => {
e(req, res)
})
proxyPath = `/proxy/${nhooyrDevServer.port()}/wsup`
absProxyPath = proxyPath.replace("/proxy/", "/absproxy/")
})
afterAll(async () => {
await nhooyrDevServer.close()
})
beforeEach(() => {
e = express.default()
})
afterEach(async () => {
if (codeServer) {
await codeServer.close()
codeServer = undefined
}
})
it("should rewrite the base path", async () => {
e.get("/wsup", (req, res) => {
res.json("asher is the best")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath)
expect(resp.status).toBe(200)
const json = await resp.json()
expect(json).toBe("asher is the best")
})
it("should not rewrite the base path", async () => {
e.get(absProxyPath, (req, res) => {
res.json("joe is the best")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(absProxyPath)
expect(resp.status).toBe(200)
const json = await resp.json()
expect(json).toBe("joe is the best")
})
it("should rewrite redirects", async () => {
e.post("/wsup", (req, res) => {
res.redirect(307, "/finale")
})
e.post("/finale", (req, res) => {
res.json("redirect success")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath, {
method: "POST",
})
expect(resp.status).toBe(200)
expect(await resp.json()).toBe("redirect success")
})
it("should not rewrite redirects", async () => {
const finalePath = absProxyPath.replace("/wsup", "/finale")
e.post(absProxyPath, (req, res) => {
res.redirect(307, finalePath)
})
e.post(finalePath, (req, res) => {
res.json("redirect success")
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(absProxyPath, {
method: "POST",
})
expect(resp.status).toBe(200)
expect(await resp.json()).toBe("redirect success")
})
it("should allow post bodies", async () => {
e.use(bodyParser.json({ strict: false }))
e.post("/wsup", (req, res) => {
res.json(req.body)
})
codeServer = await integration.setup(["--auth=none"], "")
const resp = await codeServer.fetch(proxyPath, {
method: "post",
body: JSON.stringify("coder is the best"),
headers: {
"Content-Type": "application/json",
},
})
expect(resp.status).toBe(200)
expect(await resp.json()).toBe("coder is the best")
})
})

View File

@@ -1,5 +1,5 @@
import * as httpserver from "../../../utils/httpserver" import * as httpserver from "../../utils/httpserver"
import * as integration from "../../../utils/integration" import * as integration from "../../utils/integration"
describe("health", () => { describe("health", () => {
let codeServer: httpserver.HttpServer | undefined let codeServer: httpserver.HttpServer | undefined

View File

@@ -1,6 +1,6 @@
import { RateLimiter } from "../../../../src/node/routes/login" import { RateLimiter } from "../../../src/node/routes/login"
import * as httpserver from "../../../utils/httpserver" import * as httpserver from "../../utils/httpserver"
import * as integration from "../../../utils/integration" import * as integration from "../../utils/integration"
describe("login", () => { describe("login", () => {
describe("RateLimiter", () => { describe("RateLimiter", () => {

View File

@@ -1,8 +1,8 @@
import { promises as fs } from "fs" import { promises as fs } from "fs"
import * as path from "path" import * as path from "path"
import { tmpdir } from "../../../utils/helpers" import { tmpdir } from "../../utils/helpers"
import * as httpserver from "../../../utils/httpserver" import * as httpserver from "../../utils/httpserver"
import * as integration from "../../../utils/integration" import * as integration from "../../utils/integration"
describe("/static", () => { describe("/static", () => {
let _codeServer: httpserver.HttpServer | undefined let _codeServer: httpserver.HttpServer | undefined

View File

@@ -3,10 +3,10 @@ import { promises as fs } from "fs"
import * as net from "net" import * as net from "net"
import * as path from "path" import * as path from "path"
import * as tls from "tls" import * as tls from "tls"
import { Emitter } from "../../../src/common/emitter" import { Emitter } from "../../src/common/emitter"
import { tmpdir } from "../../../src/node/constants" import { tmpdir } from "../../src/node/constants"
import { SocketProxyProvider } from "../../../src/node/socket" import { SocketProxyProvider } from "../../src/node/socket"
import { generateCertificate } from "../../../src/node/util" import { generateCertificate } from "../../src/node/util"
describe("SocketProxyProvider", () => { describe("SocketProxyProvider", () => {
const provider = new SocketProxyProvider() const provider = new SocketProxyProvider()

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -44,7 +44,7 @@
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"baseUrl": "./" /* Base directory to resolve non-absolute module names. */, "baseUrl": "./" /* Base directory to resolve non-absolute module names. */,
"paths": { "paths": {
"code-server": ["../../../../typings/pluginapi"] "code-server": ["../../../typings/pluginapi"]
} /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */, } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */ // "typeRoots": [], /* List of folders to include type definitions from. */

View File

@@ -1,9 +1,9 @@
import { promises as fs } from "fs" import { promises as fs } from "fs"
import * as http from "http" import * as http from "http"
import * as path from "path" import * as path from "path"
import { tmpdir } from "../../../src/node/constants" import { tmpdir } from "../../src/node/constants"
import { SettingsProvider, UpdateSettings } from "../../../src/node/settings" import { SettingsProvider, UpdateSettings } from "../../src/node/settings"
import { LatestResponse, UpdateProvider } from "../../../src/node/update" import { LatestResponse, UpdateProvider } from "../../src/node/update"
describe("update", () => { describe("update", () => {
let version = "1.0.0" let version = "1.0.0"

View File

@@ -1,6 +1,6 @@
import { JSDOM } from "jsdom" import { JSDOM } from "jsdom"
import * as util from "../../../src/common/util" import * as util from "../../src/common/util"
import { createLoggerMock } from "../../utils/helpers" import { createLoggerMock } from "../utils/helpers"
const dom = new JSDOM() const dom = new JSDOM()
global.document = dom.window.document global.document = dom.window.document

View File

@@ -1,7 +1,6 @@
import { promises as fs } from "fs" import { promises as fs } from "fs"
import * as os from "os" import * as os from "os"
import * as path from "path" import * as path from "path"
import * as net from "net"
/** /**
* Return a mock of @coder/logger. * Return a mock of @coder/logger.
@@ -38,47 +37,3 @@ export async function tmpdir(testName: string): Promise<string> {
return await fs.mkdtemp(path.join(dir, `${testName}-`), { encoding: "utf8" }) return await fs.mkdtemp(path.join(dir, `${testName}-`), { encoding: "utf8" })
} }
/**
* @description Helper function to use an environment variable.
*
* @returns an array (similar to useState in React) with a function
* to set the value and reset the value
*/
export function useEnv(key: string): [(nextValue: string | undefined) => string | undefined, () => void] {
const initialValue = process.env[key]
const setValue = (nextValue: string | undefined) => (process.env[key] = nextValue)
// Node automatically converts undefined to string 'undefined'
// when assigning an environment variable.
// which is why we need to delete it if it's supposed to be undefined
// Source: https://stackoverflow.com/a/60147167
const resetValue = () => {
if (initialValue !== undefined) {
process.env[key] = initialValue
} else {
delete process.env[key]
}
}
return [setValue, resetValue]
}
/**
* Helper function to get a random port.
*
* Source: https://github.com/sindresorhus/get-port/blob/main/index.js#L23-L33
*/
export const getAvailablePort = (options?: net.ListenOptions): Promise<number> =>
new Promise((resolve, reject) => {
const server = net.createServer()
server.unref()
server.on("error", reject)
server.listen(options, () => {
// NOTE@jsjoeio: not a huge fan of the type assertion
// but it works for now.
const { port } = server.address() as net.AddressInfo
server.close(() => {
resolve(port)
})
})
})

View File

@@ -4392,10 +4392,10 @@ symbol-tree@^3.2.4:
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
tar@^6.1.0, tar@^6.1.3: tar@^6.1.0:
version "6.1.6" version "6.1.0"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.6.tgz#c23d797b0a1efe5d479b1490805c5443f3560c5d" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
integrity sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g== integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
dependencies: dependencies:
chownr "^2.0.0" chownr "^2.0.0"
fs-minipass "^2.0.0" fs-minipass "^2.0.0"

277
yarn.lock
View File

@@ -206,10 +206,10 @@
resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.1.16.tgz#ee5b1b188f680733f35c11b065bbd139d618c1e1" resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.1.16.tgz#ee5b1b188f680733f35c11b065bbd139d618c1e1"
integrity sha512-X6VB1++IkosYY6amRAiMvuvCf12NA4+ooX+gOuu5bJIkdjmh4Lz7QpJcWRdgxesvo1msriDDr9E/sDbIWf6vsQ== integrity sha512-X6VB1++IkosYY6amRAiMvuvCf12NA4+ooX+gOuu5bJIkdjmh4Lz7QpJcWRdgxesvo1msriDDr9E/sDbIWf6vsQ==
"@eslint/eslintrc@^0.4.3": "@eslint/eslintrc@^0.4.2":
version "0.4.3" version "0.4.2"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179"
integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==
dependencies: dependencies:
ajv "^6.12.4" ajv "^6.12.4"
debug "^4.1.1" debug "^4.1.1"
@@ -442,9 +442,9 @@
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
"@types/node@*", "@types/node@^14.17.1": "@types/node@*", "@types/node@^14.17.1":
version "14.17.6" version "14.17.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.6.tgz#cc61c8361c89e70c468cda464d1fa3dd7e5ebd62" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54"
integrity sha512-iBxsxU7eswQDGhlr3AiamBxOssaYxbM+NKXVil8jg9yFXvrfEFbDumLD/2dMTB+zYyg7w+Xjt8yuxfdbUHAtcQ== integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
@@ -486,9 +486,9 @@
integrity sha512-1ri+LJhh0gRxIa37IpGytdaW7yDEHeJniBSMD1BmitS07R1j63brcYCzry+l0WJvGdEKQNQ7DYXO2epgborWPw== integrity sha512-1ri+LJhh0gRxIa37IpGytdaW7yDEHeJniBSMD1BmitS07R1j63brcYCzry+l0WJvGdEKQNQ7DYXO2epgborWPw==
"@types/semver@^7.1.0": "@types/semver@^7.1.0":
version "7.3.8" version "7.3.7"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.8.tgz#508a27995498d7586dcecd77c25e289bfaf90c59" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.7.tgz#b9eb89d7dfa70d5d1ce525bc1411a35347f533a3"
integrity sha512-D/2EJvAlCEtYFEYmmlGwbGXuK886HzyCc3nZX/tkFTQdEU8jZDAgiv08P162yB17y4ZXZoq7yFAnW4GDBb9Now== integrity sha512-4g1jrL98mdOIwSOUh6LTlB0Cs9I0dQPwINUhBg7C6pN4HLr8GS8xsksJxilW6S6dQHVi2K/o+lQuQcg7LroCnw==
"@types/serve-static@*": "@types/serve-static@*":
version "1.13.9" version "1.13.9"
@@ -526,79 +526,113 @@
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
"@types/ws@^7.2.6": "@types/ws@^7.2.6":
version "7.4.7" version "7.4.6"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff"
integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@typescript-eslint/eslint-plugin@^4.7.0": "@typescript-eslint/eslint-plugin@^4.7.0":
version "4.28.5" version "4.28.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.5.tgz#8197f1473e7da8218c6a37ff308d695707835684" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.3.tgz#36cdcd9ca6f9e5cb49b9f61b970b1976708d084b"
integrity sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q== integrity sha512-jW8sEFu1ZeaV8xzwsfi6Vgtty2jf7/lJmQmDkDruBjYAbx5DA8JtbcMnP0rNPUG+oH5GoQBTSp+9613BzuIpYg==
dependencies: dependencies:
"@typescript-eslint/experimental-utils" "4.28.5" "@typescript-eslint/experimental-utils" "4.28.3"
"@typescript-eslint/scope-manager" "4.28.5" "@typescript-eslint/scope-manager" "4.28.3"
debug "^4.3.1" debug "^4.3.1"
functional-red-black-tree "^1.0.1" functional-red-black-tree "^1.0.1"
regexpp "^3.1.0" regexpp "^3.1.0"
semver "^7.3.5" semver "^7.3.5"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/experimental-utils@4.28.5": "@typescript-eslint/experimental-utils@4.28.3":
version "4.28.5" version "4.28.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.5.tgz#66c28bef115b417cf9d80812a713e0e46bb42a64" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.3.tgz#976f8c1191b37105fd06658ed57ddfee4be361ca"
integrity sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA== integrity sha512-zZYl9TnrxwEPi3FbyeX0ZnE8Hp7j3OCR+ELoUfbwGHGxWnHg9+OqSmkw2MoCVpZksPCZYpQzC559Ee9pJNHTQw==
dependencies: dependencies:
"@types/json-schema" "^7.0.7" "@types/json-schema" "^7.0.7"
"@typescript-eslint/scope-manager" "4.28.5" "@typescript-eslint/scope-manager" "4.28.3"
"@typescript-eslint/types" "4.28.5" "@typescript-eslint/types" "4.28.3"
"@typescript-eslint/typescript-estree" "4.28.5" "@typescript-eslint/typescript-estree" "4.28.3"
eslint-scope "^5.1.1" eslint-scope "^5.1.1"
eslint-utils "^3.0.0" eslint-utils "^3.0.0"
"@typescript-eslint/parser@^4.7.0": "@typescript-eslint/parser@^4.7.0":
version "4.28.5" version "4.28.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.5.tgz#9c971668f86d1b5c552266c47788a87488a47d1c" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.3.tgz#95f1d475c08268edffdcb2779993c488b6434b44"
integrity sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw== integrity sha512-ZyWEn34bJexn/JNYvLQab0Mo5e+qqQNhknxmc8azgNd4XqspVYR5oHq9O11fLwdZMRcj4by15ghSlIEq+H5ltQ==
dependencies: dependencies:
"@typescript-eslint/scope-manager" "4.28.5" "@typescript-eslint/scope-manager" "4.28.3"
"@typescript-eslint/types" "4.28.5" "@typescript-eslint/types" "4.28.3"
"@typescript-eslint/typescript-estree" "4.28.5" "@typescript-eslint/typescript-estree" "4.28.3"
debug "^4.3.1" debug "^4.3.1"
"@typescript-eslint/scope-manager@4.28.5": "@typescript-eslint/scope-manager@4.28.2":
version "4.28.5" version "4.28.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.5.tgz#3a1b70c50c1535ac33322786ea99ebe403d3b923" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz#451dce90303a3ce283750111495d34c9c204e510"
integrity sha512-PHLq6n9nTMrLYcVcIZ7v0VY1X7dK309NM8ya9oL/yG8syFINIMHxyr2GzGoBYUdv3NUfCOqtuqps0ZmcgnZTfQ== integrity sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==
dependencies: dependencies:
"@typescript-eslint/types" "4.28.5" "@typescript-eslint/types" "4.28.2"
"@typescript-eslint/visitor-keys" "4.28.5" "@typescript-eslint/visitor-keys" "4.28.2"
"@typescript-eslint/types@4.28.5": "@typescript-eslint/scope-manager@4.28.3":
version "4.28.5" version "4.28.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.5.tgz#d33edf8e429f0c0930a7c3d44e9b010354c422e9" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.3.tgz#c32ad4491b3726db1ba34030b59ea922c214e371"
integrity sha512-MruOu4ZaDOLOhw4f/6iudyks/obuvvZUAHBDSW80Trnc5+ovmViLT2ZMDXhUV66ozcl6z0LJfKs1Usldgi/WCA== integrity sha512-/8lMisZ5NGIzGtJB+QizQ5eX4Xd8uxedFfMBXOKuJGP0oaBBVEMbJVddQKDXyyB0bPlmt8i6bHV89KbwOelJiQ==
"@typescript-eslint/typescript-estree@4.28.5":
version "4.28.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.5.tgz#4906d343de693cf3d8dcc301383ed638e0441cd1"
integrity sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==
dependencies: dependencies:
"@typescript-eslint/types" "4.28.5" "@typescript-eslint/types" "4.28.3"
"@typescript-eslint/visitor-keys" "4.28.5" "@typescript-eslint/visitor-keys" "4.28.3"
"@typescript-eslint/types@4.28.2":
version "4.28.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.2.tgz#e6b9e234e0e9a66c4d25bab881661e91478223b5"
integrity sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==
"@typescript-eslint/types@4.28.3":
version "4.28.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.3.tgz#8fffd436a3bada422c2c1da56060a0566a9506c7"
integrity sha512-kQFaEsQBQVtA9VGVyciyTbIg7S3WoKHNuOp/UF5RG40900KtGqfoiETWD/v0lzRXc+euVE9NXmfer9dLkUJrkA==
"@typescript-eslint/typescript-estree@4.28.2":
version "4.28.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz#680129b2a285289a15e7c6108c84739adf3a798c"
integrity sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==
dependencies:
"@typescript-eslint/types" "4.28.2"
"@typescript-eslint/visitor-keys" "4.28.2"
debug "^4.3.1" debug "^4.3.1"
globby "^11.0.3" globby "^11.0.3"
is-glob "^4.0.1" is-glob "^4.0.1"
semver "^7.3.5" semver "^7.3.5"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/visitor-keys@4.28.5": "@typescript-eslint/typescript-estree@4.28.3":
version "4.28.5" version "4.28.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.5.tgz#ffee2c602762ed6893405ee7c1144d9cc0a29675" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.3.tgz#253d7088100b2a38aefe3c8dd7bd1f8232ec46fb"
integrity sha512-dva/7Rr+EkxNWdJWau26xU/0slnFlkh88v3TsyTgRS/IIYFi5iIfpCFM4ikw0vQTFUR9FYSSyqgK4w64gsgxhg== integrity sha512-YAb1JED41kJsqCQt1NcnX5ZdTA93vKFCMP4lQYG6CFxd0VzDJcKttRlMrlG+1qiWAw8+zowmHU1H0OzjWJzR2w==
dependencies: dependencies:
"@typescript-eslint/types" "4.28.5" "@typescript-eslint/types" "4.28.3"
"@typescript-eslint/visitor-keys" "4.28.3"
debug "^4.3.1"
globby "^11.0.3"
is-glob "^4.0.1"
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/visitor-keys@4.28.2":
version "4.28.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz#bf56a400857bb68b59b311e6d0a5fbef5c3b5130"
integrity sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==
dependencies:
"@typescript-eslint/types" "4.28.2"
eslint-visitor-keys "^2.0.0"
"@typescript-eslint/visitor-keys@4.28.3":
version "4.28.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.3.tgz#26ac91e84b23529968361045829da80a4e5251c4"
integrity sha512-ri1OzcLnk1HH4gORmr1dllxDzzrN6goUIz/P4MHFV0YZJDCADPR3RvYNp0PW2SetKTThar6wlbFTL00hV2Q+fg==
dependencies:
"@typescript-eslint/types" "4.28.3"
eslint-visitor-keys "^2.0.0" eslint-visitor-keys "^2.0.0"
JSONStream@^1.0.3, JSONStream@^1.3.5: JSONStream@^1.0.3, JSONStream@^1.3.5:
@@ -1256,16 +1290,16 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codecov@^3.8.3: codecov@^3.8.1:
version "3.8.3" version "3.8.2"
resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.3.tgz#9c3e364b8a700c597346ae98418d09880a3fdbe7" resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.2.tgz#ab24f18783998c39e809ea210af899f8dbcc790e"
integrity sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA== integrity sha512-6w/kt/xvmPsWMfDFPE/T054txA9RTgcJEw36PNa6MYX+YV29jCHCRFXwbQ3QZBTOgnex1J2WP8bo2AT8TWWz9g==
dependencies: dependencies:
argv "0.0.2" argv "0.0.2"
ignore-walk "3.0.4" ignore-walk "3.0.3"
js-yaml "3.14.1" js-yaml "3.14.1"
teeny-request "7.1.1" teeny-request "7.0.1"
urlgrey "1.0.0" urlgrey "0.4.4"
collapse-white-space@^1.0.2: collapse-white-space@^1.0.2:
version "1.0.6" version "1.0.6"
@@ -1559,15 +1593,14 @@ defined@^1.0.0:
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
degenerator@^3.0.1: degenerator@^2.2.0:
version "3.0.1" version "2.2.0"
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-3.0.1.tgz#7ef78ec0c8577a544477308ddf1d2d6e88d51f5b" resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-2.2.0.tgz#49e98c11fa0293c5b26edfbb52f15729afcdb254"
integrity sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ== integrity sha512-aiQcQowF01RxFI4ZLFMpzyotbQonhNpBao6dkI8JPk5a+hmSjR5ErHp2CQySmQe8os3VBqLCIh87nDBgZXvsmg==
dependencies: dependencies:
ast-types "^0.13.2" ast-types "^0.13.2"
escodegen "^1.8.1" escodegen "^1.8.1"
esprima "^4.0.0" esprima "^4.0.0"
vm2 "^3.9.3"
delegates@^1.0.0: delegates@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -1974,12 +2007,12 @@ eslint-visitor-keys@^2.0.0:
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
eslint@^7.7.0: eslint@^7.7.0:
version "7.31.0" version "7.30.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.31.0.tgz#f972b539424bf2604907a970860732c5d99d3aca" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8"
integrity sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA== integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==
dependencies: dependencies:
"@babel/code-frame" "7.12.11" "@babel/code-frame" "7.12.11"
"@eslint/eslintrc" "^0.4.3" "@eslint/eslintrc" "^0.4.2"
"@humanwhocodes/config-array" "^0.5.0" "@humanwhocodes/config-array" "^0.5.0"
ajv "^6.10.0" ajv "^6.10.0"
chalk "^4.0.0" chalk "^4.0.0"
@@ -2184,13 +2217,6 @@ fast-safe-stringify@^2.0.7:
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
fast-url-parser@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d"
integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=
dependencies:
punycode "^1.3.2"
fastest-levenshtein@^1.0.12: fastest-levenshtein@^1.0.12:
version "1.0.12" version "1.0.12"
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
@@ -2659,10 +2685,10 @@ ieee754@^1.1.13, ieee754@^1.1.4:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore-walk@3.0.4: ignore-walk@3.0.3:
version "3.0.4" version "3.0.3"
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
dependencies: dependencies:
minimatch "^3.0.4" minimatch "^3.0.4"
@@ -3643,10 +3669,10 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pac-proxy-agent@^5.0.0: pac-proxy-agent@^4.1.0:
version "5.0.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz#b718f76475a6a5415c2efbe256c1c971c84f635e" resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-4.1.0.tgz#66883eeabadc915fc5e95457324cb0f0ac78defb"
integrity sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ== integrity sha512-ejNgYm2HTXSIYX9eFlkvqFp8hyJ374uDf0Zq5YUAifiSh1D6fo+iBivQZirGvVv8dCYUsLhmLBRhlAYvBKI5+Q==
dependencies: dependencies:
"@tootallnate/once" "1" "@tootallnate/once" "1"
agent-base "6" agent-base "6"
@@ -3654,16 +3680,16 @@ pac-proxy-agent@^5.0.0:
get-uri "3" get-uri "3"
http-proxy-agent "^4.0.1" http-proxy-agent "^4.0.1"
https-proxy-agent "5" https-proxy-agent "5"
pac-resolver "^5.0.0" pac-resolver "^4.1.0"
raw-body "^2.2.0" raw-body "^2.2.0"
socks-proxy-agent "5" socks-proxy-agent "5"
pac-resolver@^5.0.0: pac-resolver@^4.1.0:
version "5.0.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-5.0.0.tgz#1d717a127b3d7a9407a16d6e1b012b13b9ba8dc0" resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-4.2.0.tgz#b82bcb9992d48166920bc83c7542abb454bd9bdd"
integrity sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA== integrity sha512-rPACZdUyuxT5Io/gFKUeeZFfE5T7ve7cAkE5TUZRRfuKP0u5Hocwe48X7ZEm6mYB+bTB0Qf+xlVlA/RM/i6RCQ==
dependencies: dependencies:
degenerator "^3.0.1" degenerator "^2.2.0"
ip "^1.1.5" ip "^1.1.5"
netmask "^2.0.1" netmask "^2.0.1"
@@ -3978,17 +4004,17 @@ proxy-addr@~2.0.5:
forwarded "~0.1.2" forwarded "~0.1.2"
ipaddr.js "1.9.1" ipaddr.js "1.9.1"
proxy-agent@^5.0.0: proxy-agent@^4.0.0:
version "5.0.0" version "4.0.1"
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-5.0.0.tgz#d31405c10d6e8431fde96cba7a0c027ce01d633b" resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-4.0.1.tgz#326c3250776c7044cd19655ccbfadf2e065a045c"
integrity sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g== integrity sha512-ODnQnW2jc/FUVwHHuaZEfN5otg/fMbvMxz9nMSUQfJ9JU7q2SZvSULSsjLloVgJOiv9yhc8GlNMKc4GkFmcVEA==
dependencies: dependencies:
agent-base "^6.0.0" agent-base "^6.0.0"
debug "4" debug "4"
http-proxy-agent "^4.0.0" http-proxy-agent "^4.0.0"
https-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0"
lru-cache "^5.1.1" lru-cache "^5.1.1"
pac-proxy-agent "^5.0.0" pac-proxy-agent "^4.1.0"
proxy-from-env "^1.0.0" proxy-from-env "^1.0.0"
socks-proxy-agent "^5.0.0" socks-proxy-agent "^5.0.0"
@@ -4032,13 +4058,6 @@ punycode@^2.1.0:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@6.10.1:
version "6.10.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a"
integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==
dependencies:
side-channel "^1.0.4"
qs@6.7.0: qs@6.7.0:
version "6.7.0" version "6.7.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
@@ -4452,15 +4471,6 @@ shellcheck@^1.0.0:
resolved "https://registry.yarnpkg.com/shellcheck/-/shellcheck-1.0.0.tgz#263479d92c3708d63d98883f896481461cf17cd0" resolved "https://registry.yarnpkg.com/shellcheck/-/shellcheck-1.0.0.tgz#263479d92c3708d63d98883f896481461cf17cd0"
integrity sha512-CdKbWXOknBwE1wNQzAnwfLf7QNOu/yqyLSGBKoq2WuChEqfg7dnZJ1pHR2P463PbVpBRz3KGkYnXJCoQrPwtYA== integrity sha512-CdKbWXOknBwE1wNQzAnwfLf7QNOu/yqyLSGBKoq2WuChEqfg7dnZJ1pHR2P463PbVpBRz3KGkYnXJCoQrPwtYA==
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
dependencies:
call-bind "^1.0.0"
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
signal-exit@^3.0.0, signal-exit@^3.0.2: signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
@@ -4882,10 +4892,10 @@ tar-stream@^2.1.4:
inherits "^2.0.3" inherits "^2.0.3"
readable-stream "^3.1.1" readable-stream "^3.1.1"
tar@^6.1.0, tar@^6.1.3: tar@^6.1.0:
version "6.1.6" version "6.1.0"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.6.tgz#c23d797b0a1efe5d479b1490805c5443f3560c5d" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
integrity sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g== integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
dependencies: dependencies:
chownr "^2.0.0" chownr "^2.0.0"
fs-minipass "^2.0.0" fs-minipass "^2.0.0"
@@ -4894,10 +4904,10 @@ tar@^6.1.0, tar@^6.1.3:
mkdirp "^1.0.3" mkdirp "^1.0.3"
yallist "^4.0.0" yallist "^4.0.0"
teeny-request@7.1.1: teeny-request@7.0.1:
version "7.1.1" version "7.0.1"
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.1.1.tgz#2b0d156f4a8ad81de44303302ba8d7f1f05e20e6" resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.0.1.tgz#bdd41fdffea5f8fbc0d29392cb47bec4f66b2b4c"
integrity sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg== integrity sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==
dependencies: dependencies:
http-proxy-agent "^4.0.0" http-proxy-agent "^4.0.0"
https-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0"
@@ -5222,12 +5232,10 @@ url@~0.11.0:
punycode "1.3.2" punycode "1.3.2"
querystring "0.2.0" querystring "0.2.0"
urlgrey@1.0.0: urlgrey@0.4.4:
version "1.0.0" version "0.4.4"
resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-1.0.0.tgz#72d2f904482d0b602e3c7fa599343d699bbe1017" resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f"
integrity sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w== integrity sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=
dependencies:
fast-url-parser "^1.1.3"
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2" version "1.0.2"
@@ -5319,11 +5327,6 @@ vm-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
vm2@^3.9.3:
version "3.9.3"
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.3.tgz#29917f6cc081cc43a3f580c26c5b553fd3c91f40"
integrity sha512-smLS+18RjXYMl9joyJxMNI9l4w7biW8ilSDaVRvFBDwOH8P0BK1ognFQTpg0wyQ6wIKLTblHJvROW692L/E53Q==
which-boxed-primitive@^1.0.2: which-boxed-primitive@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
@@ -5403,10 +5406,10 @@ write-file-atomic@^3.0.3:
signal-exit "^3.0.2" signal-exit "^3.0.2"
typedarray-to-buffer "^3.1.5" typedarray-to-buffer "^3.1.5"
ws@^8.0.0: ws@^7.2.0:
version "8.0.0" version "7.5.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.0.0.tgz#550605d13dfc1437c9ec1396975709c6d7ffc57d" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74"
integrity sha512-6AcSIXpBlS0QvCVKk+3cWnWElLsA6SzC0lkQ43ciEglgXJXiCWK3/CGFEJ+Ybgp006CMibamAsqOlxE9s4AvYA== integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==
x-is-string@^0.1.0: x-is-string@^0.1.0:
version "0.1.0" version "0.1.0"
@@ -5479,9 +5482,9 @@ yargs@^15.0.0:
yargs-parser "^18.1.2" yargs-parser "^18.1.2"
yarn@^1.22.4: yarn@^1.22.4:
version "1.22.11" version "1.22.10"
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.11.tgz#d0104043e7349046e0e2aec977c24be106925ed6" resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c"
integrity sha512-AWje4bzqO9RUn3sdnM5N8n4ZJ0BqCc/kqFJvpOI5/EVkINXui0yuvU7NDCEF//+WaxHuNay2uOHxA4+tq1P3cg== integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==
yn@3.1.1: yn@3.1.1:
version "3.1.1" version "3.1.1"