mirror of
https://github.com/coder/code-server.git
synced 2026-04-15 00:09:58 -05:00
Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
911af4075f | ||
|
|
73380379da | ||
|
|
f75edc26b7 | ||
|
|
99503fb546 | ||
|
|
56f0c4e193 | ||
|
|
dbb8cfb315 | ||
|
|
570cb69832 | ||
|
|
379486ac38 | ||
|
|
afb8662d4d | ||
|
|
d9df02e807 | ||
|
|
ff3b188864 | ||
|
|
9137816e33 | ||
|
|
42cfa4a7ca | ||
|
|
7e43f7d6b0 | ||
|
|
93c89ba0e8 | ||
|
|
0283c35225 | ||
|
|
7a6ec202ba | ||
|
|
7a5c457209 | ||
|
|
16f2bbd007 | ||
|
|
36be0b724d | ||
|
|
18b1776cf0 | ||
|
|
56ba22f142 | ||
|
|
e442542c5e | ||
|
|
46e7d7ae7c | ||
|
|
396e2574df | ||
|
|
6d928a0666 | ||
|
|
85d8c14b92 | ||
|
|
3969a3990a | ||
|
|
162f70ac1a | ||
|
|
5b5a1f4f97 | ||
|
|
05a97c3e75 | ||
|
|
e91b910f75 | ||
|
|
ad85573e8f | ||
|
|
4e489f19b5 | ||
|
|
67e9eca942 | ||
|
|
be0e5de7eb | ||
|
|
8ca8762591 | ||
|
|
7b8cd25c0c | ||
|
|
911cb034f5 | ||
|
|
670f0a152f | ||
|
|
d0d739bec8 | ||
|
|
dfc88e3e63 | ||
|
|
7ac015ed80 | ||
|
|
da4f87a7dc | ||
|
|
cb778d6f36 | ||
|
|
6e33dccb40 | ||
|
|
5c61318592 | ||
|
|
d71649acb4 | ||
|
|
0f451524f9 | ||
|
|
a84dd25bdf | ||
|
|
52c3b0d9b4 | ||
|
|
597cdcb44d | ||
|
|
9d6a154352 | ||
|
|
37b5631795 | ||
|
|
d44c31f896 | ||
|
|
8e8abc4817 | ||
|
|
475ae45853 | ||
|
|
2d022b828d | ||
|
|
f96bcdc91e | ||
|
|
c3c57e5516 | ||
|
|
3946a5cf2e | ||
|
|
7cfd149cd3 | ||
|
|
f9f3f38578 | ||
|
|
589982f027 | ||
|
|
f720b63583 | ||
|
|
9ef6680adc | ||
|
|
a32df56f99 | ||
|
|
4cfa384bb4 | ||
|
|
3c0799fa59 | ||
|
|
8608d8ec74 | ||
|
|
903f8d9cc2 | ||
|
|
edc50ec7fb | ||
|
|
52579f182d |
5
.github/ISSUE_TEMPLATE/bug-report.md
vendored
5
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -62,6 +62,11 @@ Additionally, collecting core dumps (you may need to enable them first) if
|
||||
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
|
||||
|
||||
<!-- Ideally provide a screenshot, gif, video or screen recording. -->
|
||||
|
||||
3
.github/codecov.yml
vendored
3
.github/codecov.yml
vendored
@@ -5,7 +5,8 @@ codecov:
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "70...100"
|
||||
range: "40...70"
|
||||
patch: off
|
||||
|
||||
parsers:
|
||||
gcov:
|
||||
|
||||
32
.github/dependabot.yml
vendored
32
.github/dependabot.yml
vendored
@@ -1,32 +0,0 @@
|
||||
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"]
|
||||
73
.github/workflows/ci.yaml
vendored
73
.github/workflows/ci.yaml
vendored
@@ -352,8 +352,8 @@ jobs:
|
||||
with:
|
||||
node-version: "14"
|
||||
|
||||
- name: Install playwright
|
||||
uses: microsoft/playwright-github-action@v1
|
||||
- name: Install playwright OS dependencies
|
||||
run: npx playwright install-deps
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
@@ -402,73 +402,6 @@ jobs:
|
||||
- name: Remove release packages and test artifacts
|
||||
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:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
@@ -476,7 +409,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
#Commit SHA for v0.0.17
|
||||
uses: aquasecurity/trivy-action@ac8de07fd168680dd0331bef43681c0e150e9ad1
|
||||
uses: aquasecurity/trivy-action@9438b49cc3156b2e8c77c1ba8ffbaa3bae24e3c2
|
||||
with:
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
|
||||
28
.github/workflows/docker.yaml
vendored
Normal file
28
.github/workflows/docker.yaml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
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 }}
|
||||
@@ -1,4 +1,4 @@
|
||||
name: publish
|
||||
name: Publish on npm and brew
|
||||
|
||||
on:
|
||||
# Shows the manual trigger in GitHub UI
|
||||
@@ -22,20 +22,6 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_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:
|
||||
# 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
|
||||
1
.node-version
Normal file
1
.node-version
Normal file
@@ -0,0 +1 @@
|
||||
14
|
||||
@@ -78,8 +78,8 @@ You can disable minification by setting `MINIFY=`.
|
||||
|
||||
This directory contains the release docker container image.
|
||||
|
||||
- [./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`.
|
||||
- [./ci/steps/build-docker-buildx-push.sh](./ci/steps/docker-buildx-push.sh)
|
||||
- Builds the release containers with tags `codercom/code-server-$ARCH:$VERSION` for amd64 and arm64 with `docker buildx` and pushes them.
|
||||
- Assumes debian releases are ready in `./release-packages`.
|
||||
|
||||
## images
|
||||
@@ -107,8 +107,8 @@ Helps avoid clobbering the CI configuration.
|
||||
release packages into `./release-packages`.
|
||||
- [./steps/publish-npm.sh](./steps/publish-npm.sh)
|
||||
- Grabs the `npm-package` release artifact for the current commit and publishes it on npm.
|
||||
- [./steps/build-docker-image.sh](./steps/build-docker-image.sh)
|
||||
- Builds the docker image and then saves it into `./release-images/code-server-$ARCH-$VERSION.tar`.
|
||||
- [./steps/docker-buildx-push.sh](./steps/docker-buildx-push.sh)
|
||||
- Builds the docker image and then pushes it.
|
||||
- [./steps/push-docker-manifest.sh](./steps/push-docker-manifest.sh)
|
||||
- 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
|
||||
|
||||
@@ -3,7 +3,7 @@ set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
cd test/unit/test-plugin
|
||||
cd test/unit/node/test-plugin
|
||||
make -s out/index.js
|
||||
# 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
|
||||
|
||||
@@ -20,4 +20,4 @@ version: 1.0.3
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
appVersion: 3.10.2
|
||||
appVersion: 3.11.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# code-server
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
[code-server](https://github.com/cdr/code-server) code-server is VS Code running
|
||||
on a remote server, accessible through the browser.
|
||||
@@ -73,7 +73,7 @@ and their default values.
|
||||
| hostnameOverride | string | `""` | |
|
||||
| image.pullPolicy | string | `"Always"` | |
|
||||
| image.repository | string | `"codercom/code-server"` | |
|
||||
| image.tag | string | `"3.10.2"` | |
|
||||
| image.tag | string | `"3.11.1"` | |
|
||||
| imagePullSecrets | list | `[]` | |
|
||||
| ingress.enabled | bool | `false` | |
|
||||
| nameOverride | string | `""` | |
|
||||
|
||||
@@ -6,7 +6,7 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: codercom/code-server
|
||||
tag: '3.10.2'
|
||||
tag: '3.11.1'
|
||||
pullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
@@ -57,12 +57,12 @@ arch() {
|
||||
# https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
|
||||
get_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 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)
|
||||
if [[ -z "$artifacts_url" ]]; then
|
||||
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: $code_server_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: $VERSION and a branch named $version_branch"
|
||||
echo >&2 "URL used for gh API call: $workflow_runs_url"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -7,19 +7,11 @@ variable "VERSION" {
|
||||
}
|
||||
|
||||
group "default" {
|
||||
targets = ["code-server-amd64", "code-server-arm64"]
|
||||
targets = ["code-server"]
|
||||
}
|
||||
|
||||
target "code-server-amd64" {
|
||||
target "code-server" {
|
||||
dockerfile = "ci/release-image/Dockerfile"
|
||||
tags = ["docker.io/codercom/code-server-amd64:${VERSION}"]
|
||||
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"]
|
||||
tags = ["docker.io/codercom/code-server:${VERSION}"]
|
||||
platforms = ["linux/amd64", "linux/arm64"]
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@ main() {
|
||||
echo "Adding Homebrew/homebrew-core as $(upstream)"
|
||||
git remote add upstream https://github.com/Homebrew/homebrew-core.git
|
||||
|
||||
echo "Fetching upstream commits..."
|
||||
echo "Fetching upstream Homebrew/hombrew-core commits"
|
||||
git fetch upstream
|
||||
|
||||
echo "Merging in latest changes"
|
||||
echo "Merging in latest Homebrew/homebrew-core changes"
|
||||
git merge upstream/master
|
||||
|
||||
echo "Pushing changes to cdrci/homebrew-core fork on GitHub"
|
||||
@@ -37,7 +37,15 @@ main() {
|
||||
|
||||
# Find the docs for bump-formula-pr here
|
||||
# https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/bump-formula-pr.rb#L18
|
||||
brew bump-formula-pr --force --version="${VERSION}" code-server --no-browse --no-audit
|
||||
local output
|
||||
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
|
||||
cd ..
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/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 "$@"
|
||||
37
ci/steps/docker-buildx-push.sh
Executable file
37
ci/steps/docker-buildx-push.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/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 "$@"
|
||||
@@ -5,6 +5,14 @@ main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
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
|
||||
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
|
||||
fi
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/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 "$@"
|
||||
@@ -29,6 +29,7 @@ Here is what is needed:
|
||||
|
||||
- `node` v14.x
|
||||
- `git` v2.x or greater
|
||||
- [`git-lfs`](https://git-lfs.github.com)
|
||||
- [`yarn`](https://classic.yarnpkg.com/en/)
|
||||
- Used to install JS packages and run scripts
|
||||
- [`nfpm`](https://classic.yarnpkg.com/en/)
|
||||
@@ -142,7 +143,7 @@ Our unit tests are written in TypeScript and run using
|
||||
|
||||
These live under [test/unit](../test/unit).
|
||||
|
||||
We use unit tests for functions and things that can be tested in isolation.
|
||||
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.
|
||||
|
||||
### Integration tests
|
||||
|
||||
|
||||
12
docs/FAQ.md
12
docs/FAQ.md
@@ -28,7 +28,6 @@
|
||||
- [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)
|
||||
- [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)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
@@ -390,20 +389,13 @@ 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
|
||||
machine with few limitations.
|
||||
|
||||
<<<<<<< HEAD
|
||||
|
||||
## Does code-server have any security login validation?
|
||||
|
||||
code-server only supports a single password and limits logins to two per minute plus twelve per hour.
|
||||
|
||||
## Enterprise
|
||||
|
||||
=======
|
||||
code-server supports setting a single password and limits logins to two per
|
||||
minute plus an additional twelve per hour.
|
||||
|
||||
## Are there community projects involving code-server?
|
||||
|
||||
> > > > > > > Edit code-server docs
|
||||
|
||||
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
|
||||
add your own!
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# code-server
|
||||
|
||||
[](https://github.com/cdr/code-server/discussions) [](https://cdr.co/join-community) [](https://twitter.com/coderhq) [](https://codecov.io/gh/cdr/code-server) [](https://github.com/cdr/code-server/tree/v3.10.2/docs)
|
||||
[](https://github.com/cdr/code-server/discussions) [](https://cdr.co/join-community) [](https://twitter.com/coderhq) [](https://codecov.io/gh/cdr/code-server) [](https://github.com/cdr/code-server/tree/v3.11.1/docs)
|
||||
|
||||
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and
|
||||
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
|
||||
possible.
|
||||
2. Manually [installing
|
||||
code-server](https://coder.com/docs/code-server/v3.10.2/install)
|
||||
code-server](https://coder.com/docs/code-server/v3.11.1/install)
|
||||
3. Using our one-click buttons and guides to [deploy code-server to a cloud
|
||||
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.
|
||||
|
||||
We also have an in-depth [setup and
|
||||
configuration](https://coder.com/docs/code-server/v3.10.2/guide) guide.
|
||||
configuration](https://coder.com/docs/code-server/v3.11.1/guide) guide.
|
||||
|
||||
### code-server --link
|
||||
|
||||
@@ -71,11 +71,11 @@ Proxying code-server, you can access your IDE at https://example.cdr.co
|
||||
## Questions?
|
||||
|
||||
See answers to [frequently asked
|
||||
questions](https://coder.com/docs/code-server/v3.10.2/FAQ).
|
||||
questions](https://coder.com/docs/code-server/v3.11.1/FAQ).
|
||||
|
||||
## Want to help?
|
||||
|
||||
See [Contributing](https://coder.com/docs/code-server/v3.10.2/CONTRIBUTING) for
|
||||
See [Contributing](https://coder.com/docs/code-server/v3.11.1/CONTRIBUTING) for
|
||||
details.
|
||||
|
||||
## Hiring
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
- [Using Let's Encrypt with NGINX](#using-lets-encrypt-with-nginx)
|
||||
- [Using a self-signed certificate](#using-a-self-signed-certificate)
|
||||
- [External authentication](#external-authentication)
|
||||
- [HTTPS](#https)
|
||||
- [Self Signed Certificate](#self-signed-certificate)
|
||||
- [HTTPS and self-signed certificates](#https-and-self-signed-certificates)
|
||||
- [Accessing web services](#accessing-web-services)
|
||||
- [Using a subdomain](#using-a-subdomain)
|
||||
- [Using a subpath](#using-a-subpath)
|
||||
- [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)
|
||||
- [Cloudflare Access](https://teams.cloudflare.com/access)
|
||||
|
||||
## HTTPS
|
||||
## HTTPS and self-signed certificates
|
||||
|
||||
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.
|
||||
|
||||
### Self Signed Certificate
|
||||
## Accessing web services
|
||||
|
||||
If you're working on a web service and want to access it locally, code-server
|
||||
If you're working on web services and want to access it locally, code-server
|
||||
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.
|
||||
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
- [Raspberry Pi](#raspberry-pi)
|
||||
- [Termux](#termux)
|
||||
- [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 -->
|
||||
|
||||
@@ -229,7 +234,7 @@ alternative](https://hub.docker.com/r/linuxserver/code-server).
|
||||
|
||||
## Helm
|
||||
|
||||
You can install code-server via [Helm](../ci/helm-chart/README.md).
|
||||
You can install code-server via [Helm](https://github.com/cdr/code-server/blob/main/ci/helm-chart/README.md).
|
||||
|
||||
## Raspberry Pi
|
||||
|
||||
@@ -246,3 +251,54 @@ information.
|
||||
We maintain [one-click apps and install scripts for cloud
|
||||
providers](https://github.com/cdr/deploy-code-server) such as DigitalOcean,
|
||||
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
|
||||
```
|
||||
|
||||
88
docs/manifest.json
Normal file
88
docs/manifest.json
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -9,7 +9,7 @@ At the minimum, we recommend:
|
||||
- 2 CPU cores
|
||||
|
||||
You can use any Linux distribution, but [our
|
||||
docs](https://coder.com/docs/code-server/v3.10.2/guide) assume that you're using
|
||||
docs](https://coder.com/docs/code-server/v3.11.1/guide) assume that you're using
|
||||
Debian hosted by Google Cloud (see the following section for instructions on
|
||||
setting this up).
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
set -eu
|
||||
|
||||
# code-server's automatic install script.
|
||||
# See https://coder.com/docs/code-server/v3.10.2/install
|
||||
# See https://coder.com/docs/code-server/v3.11.1/install
|
||||
|
||||
usage() {
|
||||
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
|
||||
|
||||
More installation docs are at https://coder.com/docs/code-server/v3.10.2/install
|
||||
More installation docs are at https://coder.com/docs/code-server/v3.11.1/install
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ install_npm() {
|
||||
fi
|
||||
echoerr "Please install npm or yarn to install code-server!"
|
||||
echoerr "You will need at least node v12 and a few C dependencies."
|
||||
echoerr "See the docs https://coder.com/docs/code-server/v3.10.2/install#yarn-npm"
|
||||
echoerr "See the docs https://coder.com/docs/code-server/v3.11.1/install#yarn-npm"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -55,9 +55,12 @@ 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({
|
||||
scheme: Schemas.https,
|
||||
authority: `${resource.scheme}+${resource.authority}.${webviewRootResourceAuthority}`,
|
||||
authority: `${resource.scheme}+${authorityUrl.hostname}.${webviewRootResourceAuthority}${authorityUrl.port ? (':' + authorityUrl.port) : ''}`,
|
||||
path: resource.path,
|
||||
fragment: resource.fragment,
|
||||
query: resource.query,
|
||||
|
||||
@@ -256,7 +256,7 @@ async function processResourceRequest(event, requestUrl) {
|
||||
|
||||
const firstHostSegment = requestUrl.hostname.slice(0, requestUrl.hostname.length - (resourceBaseAuthority.length + 1));
|
||||
const scheme = firstHostSegment.split('+', 1)[0];
|
||||
const authority = firstHostSegment.slice(scheme.length + 1); // may be empty
|
||||
const authority = firstHostSegment.slice(scheme.length + 1) + requestUrl.port ? (':' + requestUrl.port) : ''; // may be empty
|
||||
|
||||
for (const parentClient of parentClients) {
|
||||
parentClient.postMessage({
|
||||
|
||||
15
package.json
15
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-server",
|
||||
"license": "MIT",
|
||||
"version": "3.10.2",
|
||||
"version": "3.11.1",
|
||||
"description": "Run VS Code on a remote server.",
|
||||
"homepage": "https://github.com/cdr/code-server",
|
||||
"bugs": {
|
||||
@@ -57,7 +57,7 @@
|
||||
"@typescript-eslint/parser": "^4.7.0",
|
||||
"audit-ci": "^4.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"codecov": "^3.8.1",
|
||||
"codecov": "^3.8.3",
|
||||
"doctoc": "^2.0.0",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
@@ -79,7 +79,8 @@
|
||||
"postcss": "^8.2.1",
|
||||
"browserslist": "^4.16.5",
|
||||
"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": {
|
||||
"@coder/logger": "1.1.16",
|
||||
@@ -94,16 +95,16 @@
|
||||
"js-yaml": "^4.0.0",
|
||||
"limiter": "^1.1.5",
|
||||
"pem": "^1.14.2",
|
||||
"proxy-agent": "^4.0.0",
|
||||
"proxy-agent": "^5.0.0",
|
||||
"proxy-from-env": "^1.1.0",
|
||||
"qs": "6.7.0",
|
||||
"qs": "6.10.1",
|
||||
"rotating-file-stream": "^2.1.1",
|
||||
"safe-buffer": "^5.1.1",
|
||||
"safe-compare": "^1.1.4",
|
||||
"semver": "^7.1.3",
|
||||
"split2": "^3.2.2",
|
||||
"tar-fs": "^2.0.0",
|
||||
"ws": "^7.2.0",
|
||||
"ws": "^8.0.0",
|
||||
"xdg-basedir": "^4.0.0",
|
||||
"yarn": "^1.22.4"
|
||||
},
|
||||
@@ -148,7 +149,7 @@
|
||||
],
|
||||
"coverageThreshold": {
|
||||
"global": {
|
||||
"lines": 40
|
||||
"lines": 60
|
||||
}
|
||||
},
|
||||
"modulePathIgnorePatterns": [
|
||||
|
||||
18
renovate.json
Normal file
18
renovate.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"rangeStrategy": "replace",
|
||||
"extends": ["config:base"],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchUpdateTypes": ["minor", "patch", "digest"],
|
||||
"automerge": true,
|
||||
"groupName": "Minor dependency updates"
|
||||
},
|
||||
{
|
||||
"matchPaths": ["lib/vscode/"],
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"vulnerabilityAlerts": {
|
||||
"enabled": "true"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import { getOptions } from "../../common/util"
|
||||
import { getOptions, Options } from "../../common/util"
|
||||
import "../register"
|
||||
|
||||
const options = getOptions()
|
||||
|
||||
// TODO: Add proper types.
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
// TODO@jsjoeio: Add proper types.
|
||||
type FixMeLater = any
|
||||
|
||||
// NOTE@jsjoeio
|
||||
// This lives here ../../../lib/vscode/src/vs/base/common/platform.ts#L106
|
||||
@@ -19,7 +17,20 @@ type NlsConfiguration = {
|
||||
_resolvedLanguagePackCoreLocation?: string
|
||||
_corruptedFile?: string
|
||||
_languagePackSupport?: boolean
|
||||
loadBundle?: any
|
||||
loadBundle?: FixMeLater
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,14 +41,10 @@ type NlsConfiguration = {
|
||||
*
|
||||
* Make sure to wrap this in a try/catch block when you call it.
|
||||
**/
|
||||
export function getNlsConfiguration(document: Document) {
|
||||
export function getNlsConfiguration(_document: Document, base: string) {
|
||||
const errorMsgPrefix = "[vscode]"
|
||||
const nlsConfigElement = document?.getElementById(nlsConfigElementId)
|
||||
const nlsConfig = nlsConfigElement?.getAttribute("data-settings")
|
||||
|
||||
if (!document) {
|
||||
throw new Error(`${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`)
|
||||
}
|
||||
const nlsConfigElement = _document?.getElementById(nlsConfigElementId)
|
||||
const dataSettings = nlsConfigElement?.getAttribute("data-settings")
|
||||
|
||||
if (!nlsConfigElement) {
|
||||
throw new Error(
|
||||
@@ -45,27 +52,34 @@ export function getNlsConfiguration(document: Document) {
|
||||
)
|
||||
}
|
||||
|
||||
if (!nlsConfig) {
|
||||
if (!dataSettings) {
|
||||
throw new Error(
|
||||
`${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`,
|
||||
)
|
||||
}
|
||||
|
||||
return JSON.parse(nlsConfig) as NlsConfiguration
|
||||
}
|
||||
const nlsConfig = JSON.parse(dataSettings) as NlsConfiguration
|
||||
|
||||
try {
|
||||
const nlsConfig = getNlsConfiguration(document)
|
||||
if (nlsConfig._resolvedLanguagePackCoreLocation) {
|
||||
const bundles = Object.create(null)
|
||||
nlsConfig.loadBundle = (bundle: any, _language: any, cb: any): void => {
|
||||
// NOTE@jsjoeio
|
||||
// Not sure why we use Object.create(null) instead of {}
|
||||
// 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]
|
||||
if (result) {
|
||||
return cb(undefined, result)
|
||||
}
|
||||
// FIXME: Only works if path separators are /.
|
||||
const path = nlsConfig._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
|
||||
fetch(`${options.base}/vscode/resource/?path=${encodeURIComponent(path)}`)
|
||||
const path = createBundlePath(nlsConfig._resolvedLanguagePackCoreLocation || "", bundle)
|
||||
fetch(`${base}/vscode/resource/?path=${encodeURIComponent(path)}`)
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
bundles[bundle] = json
|
||||
@@ -74,17 +88,61 @@ try {
|
||||
.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://.
|
||||
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
|
||||
recordStats: true,
|
||||
// TODO: There don't appear to be any types for trustedTypes yet.
|
||||
trustedTypesPolicy: (window as any).trustedTypes?.createPolicy("amdLoader", {
|
||||
trustedTypesPolicy: (_window as FixMeLater).trustedTypes?.createPolicy("amdLoader", {
|
||||
createScriptURL(value: string): string {
|
||||
if (value.startsWith(window.location.origin)) {
|
||||
return value
|
||||
}
|
||||
throw new Error(`Invalid script url: ${value}`)
|
||||
return _createScriptURL(value, window.location.origin)
|
||||
},
|
||||
}),
|
||||
paths: {
|
||||
@@ -100,25 +158,16 @@ try {
|
||||
},
|
||||
"vs/nls": nlsConfig,
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
/* Probably fine. */
|
||||
|
||||
return loader
|
||||
}
|
||||
|
||||
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]"
|
||||
|
||||
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")
|
||||
const colorThemeData = _localStorage.getItem("colorThemeData")
|
||||
|
||||
if (!colorThemeData) {
|
||||
throw new Error(
|
||||
@@ -155,14 +204,48 @@ export function setBodyBackgroundToThemeBackgroundColor(document: Document, loca
|
||||
)
|
||||
}
|
||||
|
||||
document.body.style.background = editorBgColor
|
||||
_document.body.style.background = editorBgColor
|
||||
|
||||
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 {
|
||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
||||
main(document, window, localStorage)
|
||||
} catch (error) {
|
||||
console.error("Something went wrong setting the body background to the theme background color.")
|
||||
console.error("[vscode] failed to initialize VS Code")
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ export async function registerServiceWorker(): Promise<void> {
|
||||
const options = getOptions()
|
||||
logger.level = options.logLevel
|
||||
|
||||
const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`)
|
||||
const path = normalize(`${options.csStaticBase}/out/browser/serviceWorker.js`)
|
||||
try {
|
||||
await navigator.serviceWorker.register(path, {
|
||||
scope: options.base + "/",
|
||||
|
||||
@@ -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!
|
||||
// But that's drastically unlikely.
|
||||
function shouldEnableProxy(): boolean {
|
||||
export function shouldEnableProxy(): boolean {
|
||||
let shouldEnable = false
|
||||
|
||||
const httpProxy = proxyFromEnv.getProxyForUrl(`http://example.com`)
|
||||
|
||||
@@ -63,9 +63,10 @@ router.get("/", async (req, res) => {
|
||||
* TODO: Might currently be unused.
|
||||
*/
|
||||
router.get("/resource(/*)?", ensureAuthenticated, async (req, res) => {
|
||||
if (typeof req.query.path === "string") {
|
||||
res.set("Content-Type", getMediaMime(req.query.path))
|
||||
res.send(await fs.readFile(pathToFsPath(req.query.path)))
|
||||
const path = getFirstString(req.query.path)
|
||||
if (path) {
|
||||
res.set("Content-Type", getMediaMime(path))
|
||||
res.send(await fs.readFile(pathToFsPath(path)))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -73,9 +74,10 @@ router.get("/resource(/*)?", ensureAuthenticated, async (req, res) => {
|
||||
* Used by VS Code to load files.
|
||||
*/
|
||||
router.get("/vscode-remote-resource(/*)?", ensureAuthenticated, async (req, res) => {
|
||||
if (typeof req.query.path === "string") {
|
||||
res.set("Content-Type", getMediaMime(req.query.path))
|
||||
res.send(await fs.readFile(pathToFsPath(req.query.path)))
|
||||
const path = getFirstString(req.query.path)
|
||||
if (path) {
|
||||
res.set("Content-Type", getMediaMime(path))
|
||||
res.send(await fs.readFile(pathToFsPath(path)))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -458,17 +458,11 @@ enum CharCode {
|
||||
* Taken from vs/base/common/uri.ts. It's not imported to avoid also importing
|
||||
* everything that file imports.
|
||||
*/
|
||||
export function pathToFsPath(path: string | string[], keepDriveLetterCasing = false): string {
|
||||
export function pathToFsPath(path: string, keepDriveLetterCasing = false): string {
|
||||
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
|
||||
|
||||
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") {
|
||||
// unc path: file://shares/c$/far/boo
|
||||
value = `//${uri.authority}${uri.path}`
|
||||
|
||||
@@ -16,5 +16,8 @@
|
||||
"ts-jest": "^26.4.4",
|
||||
"@types/wtfnode": "^0.7.0",
|
||||
"wtfnode": "^0.9.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"argon2/@mapbox/node-pre-gyp/tar": "^6.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { JSDOM } from "jsdom"
|
||||
import { LocationLike } from "../../util.test"
|
||||
import { LocationLike } from "../../common/util.test"
|
||||
|
||||
describe("login", () => {
|
||||
describe("there is an element with id 'base'", () => {
|
||||
|
||||
@@ -5,48 +5,47 @@ import { JSDOM } from "jsdom"
|
||||
import {
|
||||
getNlsConfiguration,
|
||||
nlsConfigElementId,
|
||||
getConfigurationForLoader,
|
||||
setBodyBackgroundToThemeBackgroundColor,
|
||||
_createScriptURL,
|
||||
main,
|
||||
createBundlePath,
|
||||
} from "../../../../src/browser/pages/vscode"
|
||||
|
||||
describe("vscode", () => {
|
||||
describe("getNlsConfiguration", () => {
|
||||
let _document: Document
|
||||
|
||||
beforeEach(() => {
|
||||
const { window } = new JSDOM()
|
||||
global.document = window.document
|
||||
// We use underscores to not confuse with global values
|
||||
const { window: _window } = new JSDOM()
|
||||
_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", () => {
|
||||
const errorMsgPrefix = "[vscode]"
|
||||
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}`
|
||||
|
||||
expect(() => {
|
||||
getNlsConfiguration(document)
|
||||
getNlsConfiguration(_document, "")
|
||||
}).toThrowError(errorMessage)
|
||||
})
|
||||
it("should throw an error if no nlsConfig", () => {
|
||||
const mockElement = document.createElement("div")
|
||||
const mockElement = _document.createElement("div")
|
||||
mockElement.setAttribute("id", nlsConfigElementId)
|
||||
document.body.appendChild(mockElement)
|
||||
_document.body.appendChild(mockElement)
|
||||
|
||||
const errorMsgPrefix = "[vscode]"
|
||||
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`
|
||||
|
||||
expect(() => {
|
||||
getNlsConfiguration(document)
|
||||
getNlsConfiguration(_document, "")
|
||||
}).toThrowError(errorMessage)
|
||||
|
||||
document.body.removeChild(mockElement)
|
||||
_document.body.removeChild(mockElement)
|
||||
})
|
||||
it("should return the correct configuration", () => {
|
||||
const mockElement = document.createElement("div")
|
||||
const mockElement = _document.createElement("div")
|
||||
const dataSettings = {
|
||||
first: "Jane",
|
||||
last: "Doe",
|
||||
@@ -54,22 +53,52 @@ describe("vscode", () => {
|
||||
|
||||
mockElement.setAttribute("id", nlsConfigElementId)
|
||||
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
|
||||
document.body.appendChild(mockElement)
|
||||
const actual = getNlsConfiguration(global.document)
|
||||
_document.body.appendChild(mockElement)
|
||||
const actual = getNlsConfiguration(_document, "")
|
||||
|
||||
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", () => {
|
||||
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-622314949
|
||||
const { window } = new JSDOM("", { url: "http://localhost" })
|
||||
global.document = window.document
|
||||
global.localStorage = window.localStorage
|
||||
const { window: _window } = new JSDOM("", { url: "http://localhost" })
|
||||
_document = _window.document
|
||||
_localStorage = _window.localStorage
|
||||
})
|
||||
it("should return null", () => {
|
||||
const test = {
|
||||
@@ -77,49 +106,31 @@ describe("vscode", () => {
|
||||
[`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")
|
||||
})
|
||||
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)
|
||||
_localStorage.removeItem("colorThemeData")
|
||||
})
|
||||
it("should throw an error if it can't find colorThemeData in localStorage", () => {
|
||||
const errorMsgPrefix = "[vscode]"
|
||||
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not find colorThemeData in localStorage.`
|
||||
|
||||
expect(() => {
|
||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
||||
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||
}).toThrowError(errorMessage)
|
||||
})
|
||||
it("should throw an error if there is an error parsing colorThemeData from localStorage", () => {
|
||||
const errorMsgPrefix = "[vscode]"
|
||||
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not parse colorThemeData from localStorage.`
|
||||
|
||||
localStorage.setItem(
|
||||
_localStorage.setItem(
|
||||
"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}',
|
||||
)
|
||||
|
||||
expect(() => {
|
||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
||||
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||
}).toThrowError(errorMessage)
|
||||
|
||||
localStorage.removeItem("colorThemeData")
|
||||
@@ -131,13 +142,13 @@ describe("vscode", () => {
|
||||
const test = {
|
||||
id: "hey-joe",
|
||||
}
|
||||
localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||
_localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||
|
||||
expect(() => {
|
||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
||||
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||
}).toThrowError(errorMessage)
|
||||
|
||||
localStorage.removeItem("colorThemeData")
|
||||
_localStorage.removeItem("colorThemeData")
|
||||
})
|
||||
it("should throw an error if there is no editor.background color", () => {
|
||||
const errorMsgPrefix = "[vscode]"
|
||||
@@ -149,13 +160,13 @@ describe("vscode", () => {
|
||||
editor: "#fff",
|
||||
},
|
||||
}
|
||||
localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||
_localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||
|
||||
expect(() => {
|
||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
||||
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||
}).toThrowError(errorMessage)
|
||||
|
||||
localStorage.removeItem("colorThemeData")
|
||||
_localStorage.removeItem("colorThemeData")
|
||||
})
|
||||
it("should set the body background to the editor background color", () => {
|
||||
const test = {
|
||||
@@ -163,16 +174,188 @@ describe("vscode", () => {
|
||||
[`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
|
||||
// it is converted to rgb
|
||||
// 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()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { JSDOM } from "jsdom"
|
||||
import { registerServiceWorker } from "../../../src/browser/register"
|
||||
import { createLoggerMock } from "../../utils/helpers"
|
||||
import { LocationLike } from "../util.test"
|
||||
import { LocationLike } from "../common/util.test"
|
||||
|
||||
describe("register", () => {
|
||||
describe("when navigator and serviceWorker are defined", () => {
|
||||
@@ -155,7 +155,7 @@ describe("register", () => {
|
||||
await registerServiceWorker()
|
||||
|
||||
expect(mockFn).toBeCalled()
|
||||
expect(serviceWorkerPath).toMatch(`${csStaticBasePath}/dist/serviceWorker.js`)
|
||||
expect(serviceWorkerPath).toMatch(`${csStaticBasePath}/out/browser/serviceWorker.js`)
|
||||
expect(serviceWorkerScope).toMatch("/")
|
||||
})
|
||||
it("should register when options.base is defined", async () => {
|
||||
@@ -176,7 +176,7 @@ describe("register", () => {
|
||||
await registerServiceWorker()
|
||||
|
||||
expect(mockFn).toBeCalled()
|
||||
expect(serviceWorkerPath).toMatch(`/dist/serviceWorker.js`)
|
||||
expect(serviceWorkerPath).toMatch(`/out/browser/serviceWorker.js`)
|
||||
expect(serviceWorkerScope).toMatch("/")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Note: we need to import logger from the root
|
||||
// because this is the logger used in logError in ../src/common/util
|
||||
import { logger } from "../../node_modules/@coder/logger"
|
||||
import { logger } from "@coder/logger"
|
||||
|
||||
import { Emitter } from "../../src/common/emitter"
|
||||
import { Emitter } from "../../../src/common/emitter"
|
||||
|
||||
describe("emitter", () => {
|
||||
let spy: jest.SpyInstance
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HttpCode, HttpError } from "../../src/common/http"
|
||||
import { HttpCode, HttpError } from "../../../src/common/http"
|
||||
|
||||
describe("http", () => {
|
||||
describe("HttpCode", () => {
|
||||
@@ -1,6 +1,6 @@
|
||||
import { JSDOM } from "jsdom"
|
||||
import * as util from "../../src/common/util"
|
||||
import { createLoggerMock } from "../utils/helpers"
|
||||
import * as util from "../../../src/common/util"
|
||||
import { createLoggerMock } from "../../utils/helpers"
|
||||
|
||||
const dom = new JSDOM()
|
||||
global.document = dom.window.document
|
||||
@@ -1,5 +1,5 @@
|
||||
import { promises as fs } from "fs"
|
||||
import { tmpdir } from "../../test/utils/helpers"
|
||||
import { getAvailablePort, tmpdir, useEnv } from "../../test/utils/helpers"
|
||||
|
||||
/**
|
||||
* This file is for testing test helpers (not core code).
|
||||
@@ -12,3 +12,43 @@ describe("test helpers", () => {
|
||||
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)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,9 +3,9 @@ import { promises as fs } from "fs"
|
||||
import * as net from "net"
|
||||
import * as os from "os"
|
||||
import * as path from "path"
|
||||
import { Args, parse, setDefaults, shouldOpenInExistingInstance, splitOnFirstEquals } from "../../src/node/cli"
|
||||
import { tmpdir } from "../../src/node/constants"
|
||||
import { paths } from "../../src/node/util"
|
||||
import { Args, parse, setDefaults, shouldOpenInExistingInstance, splitOnFirstEquals } from "../../../src/node/cli"
|
||||
import { tmpdir } from "../../../src/node/constants"
|
||||
import { paths } from "../../../src/node/util"
|
||||
|
||||
type Mutable<T> = {
|
||||
-readonly [P in keyof T]: T[P]
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createLoggerMock } from "../utils/helpers"
|
||||
import { createLoggerMock } from "../../utils/helpers"
|
||||
|
||||
describe("constants", () => {
|
||||
let constants: typeof import("../../src/node/constants")
|
||||
let constants: typeof import("../../../src/node/constants")
|
||||
|
||||
describe("with package.json defined", () => {
|
||||
const loggerModule = createLoggerMock()
|
||||
@@ -15,8 +15,8 @@ describe("constants", () => {
|
||||
|
||||
beforeAll(() => {
|
||||
jest.mock("@coder/logger", () => loggerModule)
|
||||
jest.mock("../../package.json", () => mockPackageJson, { virtual: true })
|
||||
constants = require("../../src/node/constants")
|
||||
jest.mock("../../../package.json", () => mockPackageJson, { virtual: true })
|
||||
constants = require("../../../src/node/constants")
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
@@ -57,8 +57,8 @@ describe("constants", () => {
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
jest.mock("../../package.json", () => mockPackageJson, { virtual: true })
|
||||
constants = require("../../src/node/constants")
|
||||
jest.mock("../../../package.json", () => mockPackageJson, { virtual: true })
|
||||
constants = require("../../../src/node/constants")
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
@@ -2,11 +2,11 @@ import { logger } from "@coder/logger"
|
||||
import * as express from "express"
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import { HttpCode } from "../../src/common/http"
|
||||
import { AuthType } from "../../src/node/cli"
|
||||
import { codeServer, PluginAPI } from "../../src/node/plugin"
|
||||
import * as apps from "../../src/node/routes/apps"
|
||||
import * as httpserver from "../utils/httpserver"
|
||||
import { HttpCode } from "../../../src/common/http"
|
||||
import { AuthType } from "../../../src/node/cli"
|
||||
import { codeServer, PluginAPI } from "../../../src/node/plugin"
|
||||
import * as apps from "../../../src/node/routes/apps"
|
||||
import * as httpserver from "../../utils/httpserver"
|
||||
const fsp = fs.promises
|
||||
|
||||
// Jest overrides `require` so our usual override doesn't work.
|
||||
215
test/unit/node/proxy.test.ts
Normal file
215
test/unit/node/proxy.test.ts
Normal file
@@ -0,0 +1,215 @@
|
||||
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")
|
||||
})
|
||||
})
|
||||
39
test/unit/node/proxy_agent.test.ts
Normal file
39
test/unit/node/proxy_agent.test.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
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)
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as httpserver from "../../utils/httpserver"
|
||||
import * as integration from "../../utils/integration"
|
||||
import * as httpserver from "../../../utils/httpserver"
|
||||
import * as integration from "../../../utils/integration"
|
||||
|
||||
describe("health", () => {
|
||||
let codeServer: httpserver.HttpServer | undefined
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RateLimiter } from "../../../src/node/routes/login"
|
||||
import * as httpserver from "../../utils/httpserver"
|
||||
import * as integration from "../../utils/integration"
|
||||
import { RateLimiter } from "../../../../src/node/routes/login"
|
||||
import * as httpserver from "../../../utils/httpserver"
|
||||
import * as integration from "../../../utils/integration"
|
||||
|
||||
describe("login", () => {
|
||||
describe("RateLimiter", () => {
|
||||
@@ -1,8 +1,8 @@
|
||||
import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import { tmpdir } from "../../utils/helpers"
|
||||
import * as httpserver from "../../utils/httpserver"
|
||||
import * as integration from "../../utils/integration"
|
||||
import { tmpdir } from "../../../utils/helpers"
|
||||
import * as httpserver from "../../../utils/httpserver"
|
||||
import * as integration from "../../../utils/integration"
|
||||
|
||||
describe("/static", () => {
|
||||
let _codeServer: httpserver.HttpServer | undefined
|
||||
@@ -3,10 +3,10 @@ import { promises as fs } from "fs"
|
||||
import * as net from "net"
|
||||
import * as path from "path"
|
||||
import * as tls from "tls"
|
||||
import { Emitter } from "../../src/common/emitter"
|
||||
import { tmpdir } from "../../src/node/constants"
|
||||
import { SocketProxyProvider } from "../../src/node/socket"
|
||||
import { generateCertificate } from "../../src/node/util"
|
||||
import { Emitter } from "../../../src/common/emitter"
|
||||
import { tmpdir } from "../../../src/node/constants"
|
||||
import { SocketProxyProvider } from "../../../src/node/socket"
|
||||
import { generateCertificate } from "../../../src/node/util"
|
||||
|
||||
describe("SocketProxyProvider", () => {
|
||||
const provider = new SocketProxyProvider()
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
@@ -44,7 +44,7 @@
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
"baseUrl": "./" /* Base directory to resolve non-absolute module names. */,
|
||||
"paths": {
|
||||
"code-server": ["../../../typings/pluginapi"]
|
||||
"code-server": ["../../../../typings/pluginapi"]
|
||||
} /* 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. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
@@ -1,9 +1,9 @@
|
||||
import { promises as fs } from "fs"
|
||||
import * as http from "http"
|
||||
import * as path from "path"
|
||||
import { tmpdir } from "../../src/node/constants"
|
||||
import { SettingsProvider, UpdateSettings } from "../../src/node/settings"
|
||||
import { LatestResponse, UpdateProvider } from "../../src/node/update"
|
||||
import { tmpdir } from "../../../src/node/constants"
|
||||
import { SettingsProvider, UpdateSettings } from "../../../src/node/settings"
|
||||
import { LatestResponse, UpdateProvider } from "../../../src/node/update"
|
||||
|
||||
describe("update", () => {
|
||||
let version = "1.0.0"
|
||||
@@ -1,5 +1,8 @@
|
||||
import * as cp from "child_process"
|
||||
import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import { generateUuid } from "../../../src/common/util"
|
||||
import { tmpdir } from "../../../src/node/constants"
|
||||
import * as util from "../../../src/node/util"
|
||||
|
||||
describe("getEnvPaths", () => {
|
||||
@@ -464,22 +467,8 @@ describe("pathToFsPath", () => {
|
||||
it("should keep drive letter casing when set to true", () => {
|
||||
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", () => {
|
||||
let ORIGINAL_PLATFORM = process.platform
|
||||
const ORIGINAL_PLATFORM = process.platform
|
||||
|
||||
Object.defineProperty(process, "platform", {
|
||||
value: "win32",
|
||||
@@ -492,3 +481,23 @@ 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)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
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")
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,7 @@
|
||||
import { promises as fs } from "fs"
|
||||
import * as os from "os"
|
||||
import * as path from "path"
|
||||
import * as net from "net"
|
||||
|
||||
/**
|
||||
* Return a mock of @coder/logger.
|
||||
@@ -37,3 +38,47 @@ export async function tmpdir(testName: string): Promise<string> {
|
||||
|
||||
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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4392,10 +4392,10 @@ symbol-tree@^3.2.4:
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
|
||||
|
||||
tar@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
|
||||
integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
|
||||
tar@^6.1.0, tar@^6.1.3:
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.6.tgz#c23d797b0a1efe5d479b1490805c5443f3560c5d"
|
||||
integrity sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==
|
||||
dependencies:
|
||||
chownr "^2.0.0"
|
||||
fs-minipass "^2.0.0"
|
||||
|
||||
277
yarn.lock
277
yarn.lock
@@ -206,10 +206,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.1.16.tgz#ee5b1b188f680733f35c11b065bbd139d618c1e1"
|
||||
integrity sha512-X6VB1++IkosYY6amRAiMvuvCf12NA4+ooX+gOuu5bJIkdjmh4Lz7QpJcWRdgxesvo1msriDDr9E/sDbIWf6vsQ==
|
||||
|
||||
"@eslint/eslintrc@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179"
|
||||
integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==
|
||||
"@eslint/eslintrc@^0.4.3":
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||
integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.1.1"
|
||||
@@ -442,9 +442,9 @@
|
||||
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
|
||||
|
||||
"@types/node@*", "@types/node@^14.17.1":
|
||||
version "14.17.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54"
|
||||
integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==
|
||||
version "14.17.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.6.tgz#cc61c8361c89e70c468cda464d1fa3dd7e5ebd62"
|
||||
integrity sha512-iBxsxU7eswQDGhlr3AiamBxOssaYxbM+NKXVil8jg9yFXvrfEFbDumLD/2dMTB+zYyg7w+Xjt8yuxfdbUHAtcQ==
|
||||
|
||||
"@types/normalize-package-data@^2.4.0":
|
||||
version "2.4.0"
|
||||
@@ -486,9 +486,9 @@
|
||||
integrity sha512-1ri+LJhh0gRxIa37IpGytdaW7yDEHeJniBSMD1BmitS07R1j63brcYCzry+l0WJvGdEKQNQ7DYXO2epgborWPw==
|
||||
|
||||
"@types/semver@^7.1.0":
|
||||
version "7.3.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.7.tgz#b9eb89d7dfa70d5d1ce525bc1411a35347f533a3"
|
||||
integrity sha512-4g1jrL98mdOIwSOUh6LTlB0Cs9I0dQPwINUhBg7C6pN4HLr8GS8xsksJxilW6S6dQHVi2K/o+lQuQcg7LroCnw==
|
||||
version "7.3.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.8.tgz#508a27995498d7586dcecd77c25e289bfaf90c59"
|
||||
integrity sha512-D/2EJvAlCEtYFEYmmlGwbGXuK886HzyCc3nZX/tkFTQdEU8jZDAgiv08P162yB17y4ZXZoq7yFAnW4GDBb9Now==
|
||||
|
||||
"@types/serve-static@*":
|
||||
version "1.13.9"
|
||||
@@ -526,113 +526,79 @@
|
||||
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
|
||||
|
||||
"@types/ws@^7.2.6":
|
||||
version "7.4.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff"
|
||||
integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw==
|
||||
version "7.4.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702"
|
||||
integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.7.0":
|
||||
version "4.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.3.tgz#36cdcd9ca6f9e5cb49b9f61b970b1976708d084b"
|
||||
integrity sha512-jW8sEFu1ZeaV8xzwsfi6Vgtty2jf7/lJmQmDkDruBjYAbx5DA8JtbcMnP0rNPUG+oH5GoQBTSp+9613BzuIpYg==
|
||||
version "4.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.5.tgz#8197f1473e7da8218c6a37ff308d695707835684"
|
||||
integrity sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "4.28.3"
|
||||
"@typescript-eslint/scope-manager" "4.28.3"
|
||||
"@typescript-eslint/experimental-utils" "4.28.5"
|
||||
"@typescript-eslint/scope-manager" "4.28.5"
|
||||
debug "^4.3.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
regexpp "^3.1.0"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@4.28.3":
|
||||
version "4.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.3.tgz#976f8c1191b37105fd06658ed57ddfee4be361ca"
|
||||
integrity sha512-zZYl9TnrxwEPi3FbyeX0ZnE8Hp7j3OCR+ELoUfbwGHGxWnHg9+OqSmkw2MoCVpZksPCZYpQzC559Ee9pJNHTQw==
|
||||
"@typescript-eslint/experimental-utils@4.28.5":
|
||||
version "4.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.5.tgz#66c28bef115b417cf9d80812a713e0e46bb42a64"
|
||||
integrity sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.7"
|
||||
"@typescript-eslint/scope-manager" "4.28.3"
|
||||
"@typescript-eslint/types" "4.28.3"
|
||||
"@typescript-eslint/typescript-estree" "4.28.3"
|
||||
"@typescript-eslint/scope-manager" "4.28.5"
|
||||
"@typescript-eslint/types" "4.28.5"
|
||||
"@typescript-eslint/typescript-estree" "4.28.5"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^4.7.0":
|
||||
version "4.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.3.tgz#95f1d475c08268edffdcb2779993c488b6434b44"
|
||||
integrity sha512-ZyWEn34bJexn/JNYvLQab0Mo5e+qqQNhknxmc8azgNd4XqspVYR5oHq9O11fLwdZMRcj4by15ghSlIEq+H5ltQ==
|
||||
version "4.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.5.tgz#9c971668f86d1b5c552266c47788a87488a47d1c"
|
||||
integrity sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "4.28.3"
|
||||
"@typescript-eslint/types" "4.28.3"
|
||||
"@typescript-eslint/typescript-estree" "4.28.3"
|
||||
"@typescript-eslint/scope-manager" "4.28.5"
|
||||
"@typescript-eslint/types" "4.28.5"
|
||||
"@typescript-eslint/typescript-estree" "4.28.5"
|
||||
debug "^4.3.1"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.28.2":
|
||||
version "4.28.2"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz#451dce90303a3ce283750111495d34c9c204e510"
|
||||
integrity sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==
|
||||
"@typescript-eslint/scope-manager@4.28.5":
|
||||
version "4.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.5.tgz#3a1b70c50c1535ac33322786ea99ebe403d3b923"
|
||||
integrity sha512-PHLq6n9nTMrLYcVcIZ7v0VY1X7dK309NM8ya9oL/yG8syFINIMHxyr2GzGoBYUdv3NUfCOqtuqps0ZmcgnZTfQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.28.2"
|
||||
"@typescript-eslint/visitor-keys" "4.28.2"
|
||||
"@typescript-eslint/types" "4.28.5"
|
||||
"@typescript-eslint/visitor-keys" "4.28.5"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.28.3":
|
||||
version "4.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.3.tgz#c32ad4491b3726db1ba34030b59ea922c214e371"
|
||||
integrity sha512-/8lMisZ5NGIzGtJB+QizQ5eX4Xd8uxedFfMBXOKuJGP0oaBBVEMbJVddQKDXyyB0bPlmt8i6bHV89KbwOelJiQ==
|
||||
"@typescript-eslint/types@4.28.5":
|
||||
version "4.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.5.tgz#d33edf8e429f0c0930a7c3d44e9b010354c422e9"
|
||||
integrity sha512-MruOu4ZaDOLOhw4f/6iudyks/obuvvZUAHBDSW80Trnc5+ovmViLT2ZMDXhUV66ozcl6z0LJfKs1Usldgi/WCA==
|
||||
|
||||
"@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:
|
||||
"@typescript-eslint/types" "4.28.3"
|
||||
"@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"
|
||||
"@typescript-eslint/types" "4.28.5"
|
||||
"@typescript-eslint/visitor-keys" "4.28.5"
|
||||
debug "^4.3.1"
|
||||
globby "^11.0.3"
|
||||
is-glob "^4.0.1"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.28.3":
|
||||
version "4.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.3.tgz#253d7088100b2a38aefe3c8dd7bd1f8232ec46fb"
|
||||
integrity sha512-YAb1JED41kJsqCQt1NcnX5ZdTA93vKFCMP4lQYG6CFxd0VzDJcKttRlMrlG+1qiWAw8+zowmHU1H0OzjWJzR2w==
|
||||
"@typescript-eslint/visitor-keys@4.28.5":
|
||||
version "4.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.5.tgz#ffee2c602762ed6893405ee7c1144d9cc0a29675"
|
||||
integrity sha512-dva/7Rr+EkxNWdJWau26xU/0slnFlkh88v3TsyTgRS/IIYFi5iIfpCFM4ikw0vQTFUR9FYSSyqgK4w64gsgxhg==
|
||||
dependencies:
|
||||
"@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"
|
||||
"@typescript-eslint/types" "4.28.5"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
JSONStream@^1.0.3, JSONStream@^1.3.5:
|
||||
@@ -1290,16 +1256,16 @@ code-point-at@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||
|
||||
codecov@^3.8.1:
|
||||
version "3.8.2"
|
||||
resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.2.tgz#ab24f18783998c39e809ea210af899f8dbcc790e"
|
||||
integrity sha512-6w/kt/xvmPsWMfDFPE/T054txA9RTgcJEw36PNa6MYX+YV29jCHCRFXwbQ3QZBTOgnex1J2WP8bo2AT8TWWz9g==
|
||||
codecov@^3.8.3:
|
||||
version "3.8.3"
|
||||
resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.3.tgz#9c3e364b8a700c597346ae98418d09880a3fdbe7"
|
||||
integrity sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA==
|
||||
dependencies:
|
||||
argv "0.0.2"
|
||||
ignore-walk "3.0.3"
|
||||
ignore-walk "3.0.4"
|
||||
js-yaml "3.14.1"
|
||||
teeny-request "7.0.1"
|
||||
urlgrey "0.4.4"
|
||||
teeny-request "7.1.1"
|
||||
urlgrey "1.0.0"
|
||||
|
||||
collapse-white-space@^1.0.2:
|
||||
version "1.0.6"
|
||||
@@ -1593,14 +1559,15 @@ defined@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
|
||||
integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
|
||||
|
||||
degenerator@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-2.2.0.tgz#49e98c11fa0293c5b26edfbb52f15729afcdb254"
|
||||
integrity sha512-aiQcQowF01RxFI4ZLFMpzyotbQonhNpBao6dkI8JPk5a+hmSjR5ErHp2CQySmQe8os3VBqLCIh87nDBgZXvsmg==
|
||||
degenerator@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-3.0.1.tgz#7ef78ec0c8577a544477308ddf1d2d6e88d51f5b"
|
||||
integrity sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==
|
||||
dependencies:
|
||||
ast-types "^0.13.2"
|
||||
escodegen "^1.8.1"
|
||||
esprima "^4.0.0"
|
||||
vm2 "^3.9.3"
|
||||
|
||||
delegates@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -2007,12 +1974,12 @@ eslint-visitor-keys@^2.0.0:
|
||||
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
|
||||
|
||||
eslint@^7.7.0:
|
||||
version "7.30.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8"
|
||||
integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==
|
||||
version "7.31.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.31.0.tgz#f972b539424bf2604907a970860732c5d99d3aca"
|
||||
integrity sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "7.12.11"
|
||||
"@eslint/eslintrc" "^0.4.2"
|
||||
"@eslint/eslintrc" "^0.4.3"
|
||||
"@humanwhocodes/config-array" "^0.5.0"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
@@ -2217,6 +2184,13 @@ fast-safe-stringify@^2.0.7:
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
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:
|
||||
version "1.0.12"
|
||||
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
|
||||
@@ -2685,10 +2659,10 @@ ieee754@^1.1.13, ieee754@^1.1.4:
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
ignore-walk@3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
|
||||
integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
|
||||
ignore-walk@3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335"
|
||||
integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==
|
||||
dependencies:
|
||||
minimatch "^3.0.4"
|
||||
|
||||
@@ -3669,10 +3643,10 @@ p-try@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||
|
||||
pac-proxy-agent@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-4.1.0.tgz#66883eeabadc915fc5e95457324cb0f0ac78defb"
|
||||
integrity sha512-ejNgYm2HTXSIYX9eFlkvqFp8hyJ374uDf0Zq5YUAifiSh1D6fo+iBivQZirGvVv8dCYUsLhmLBRhlAYvBKI5+Q==
|
||||
pac-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz#b718f76475a6a5415c2efbe256c1c971c84f635e"
|
||||
integrity sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==
|
||||
dependencies:
|
||||
"@tootallnate/once" "1"
|
||||
agent-base "6"
|
||||
@@ -3680,16 +3654,16 @@ pac-proxy-agent@^4.1.0:
|
||||
get-uri "3"
|
||||
http-proxy-agent "^4.0.1"
|
||||
https-proxy-agent "5"
|
||||
pac-resolver "^4.1.0"
|
||||
pac-resolver "^5.0.0"
|
||||
raw-body "^2.2.0"
|
||||
socks-proxy-agent "5"
|
||||
|
||||
pac-resolver@^4.1.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-4.2.0.tgz#b82bcb9992d48166920bc83c7542abb454bd9bdd"
|
||||
integrity sha512-rPACZdUyuxT5Io/gFKUeeZFfE5T7ve7cAkE5TUZRRfuKP0u5Hocwe48X7ZEm6mYB+bTB0Qf+xlVlA/RM/i6RCQ==
|
||||
pac-resolver@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-5.0.0.tgz#1d717a127b3d7a9407a16d6e1b012b13b9ba8dc0"
|
||||
integrity sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==
|
||||
dependencies:
|
||||
degenerator "^2.2.0"
|
||||
degenerator "^3.0.1"
|
||||
ip "^1.1.5"
|
||||
netmask "^2.0.1"
|
||||
|
||||
@@ -4004,17 +3978,17 @@ proxy-addr@~2.0.5:
|
||||
forwarded "~0.1.2"
|
||||
ipaddr.js "1.9.1"
|
||||
|
||||
proxy-agent@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-4.0.1.tgz#326c3250776c7044cd19655ccbfadf2e065a045c"
|
||||
integrity sha512-ODnQnW2jc/FUVwHHuaZEfN5otg/fMbvMxz9nMSUQfJ9JU7q2SZvSULSsjLloVgJOiv9yhc8GlNMKc4GkFmcVEA==
|
||||
proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-5.0.0.tgz#d31405c10d6e8431fde96cba7a0c027ce01d633b"
|
||||
integrity sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==
|
||||
dependencies:
|
||||
agent-base "^6.0.0"
|
||||
debug "4"
|
||||
http-proxy-agent "^4.0.0"
|
||||
https-proxy-agent "^5.0.0"
|
||||
lru-cache "^5.1.1"
|
||||
pac-proxy-agent "^4.1.0"
|
||||
pac-proxy-agent "^5.0.0"
|
||||
proxy-from-env "^1.0.0"
|
||||
socks-proxy-agent "^5.0.0"
|
||||
|
||||
@@ -4058,6 +4032,13 @@ punycode@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
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:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
@@ -4471,6 +4452,15 @@ shellcheck@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/shellcheck/-/shellcheck-1.0.0.tgz#263479d92c3708d63d98883f896481461cf17cd0"
|
||||
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:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
@@ -4892,10 +4882,10 @@ tar-stream@^2.1.4:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^3.1.1"
|
||||
|
||||
tar@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
|
||||
integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
|
||||
tar@^6.1.0, tar@^6.1.3:
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.6.tgz#c23d797b0a1efe5d479b1490805c5443f3560c5d"
|
||||
integrity sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==
|
||||
dependencies:
|
||||
chownr "^2.0.0"
|
||||
fs-minipass "^2.0.0"
|
||||
@@ -4904,10 +4894,10 @@ tar@^6.1.0:
|
||||
mkdirp "^1.0.3"
|
||||
yallist "^4.0.0"
|
||||
|
||||
teeny-request@7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.0.1.tgz#bdd41fdffea5f8fbc0d29392cb47bec4f66b2b4c"
|
||||
integrity sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==
|
||||
teeny-request@7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.1.1.tgz#2b0d156f4a8ad81de44303302ba8d7f1f05e20e6"
|
||||
integrity sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==
|
||||
dependencies:
|
||||
http-proxy-agent "^4.0.0"
|
||||
https-proxy-agent "^5.0.0"
|
||||
@@ -5232,10 +5222,12 @@ url@~0.11.0:
|
||||
punycode "1.3.2"
|
||||
querystring "0.2.0"
|
||||
|
||||
urlgrey@0.4.4:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f"
|
||||
integrity sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=
|
||||
urlgrey@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-1.0.0.tgz#72d2f904482d0b602e3c7fa599343d699bbe1017"
|
||||
integrity sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w==
|
||||
dependencies:
|
||||
fast-url-parser "^1.1.3"
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
@@ -5327,6 +5319,11 @@ vm-browserify@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
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:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
|
||||
@@ -5406,10 +5403,10 @@ write-file-atomic@^3.0.3:
|
||||
signal-exit "^3.0.2"
|
||||
typedarray-to-buffer "^3.1.5"
|
||||
|
||||
ws@^7.2.0:
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74"
|
||||
integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==
|
||||
ws@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.0.0.tgz#550605d13dfc1437c9ec1396975709c6d7ffc57d"
|
||||
integrity sha512-6AcSIXpBlS0QvCVKk+3cWnWElLsA6SzC0lkQ43ciEglgXJXiCWK3/CGFEJ+Ybgp006CMibamAsqOlxE9s4AvYA==
|
||||
|
||||
x-is-string@^0.1.0:
|
||||
version "0.1.0"
|
||||
@@ -5482,9 +5479,9 @@ yargs@^15.0.0:
|
||||
yargs-parser "^18.1.2"
|
||||
|
||||
yarn@^1.22.4:
|
||||
version "1.22.10"
|
||||
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c"
|
||||
integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==
|
||||
version "1.22.11"
|
||||
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.11.tgz#d0104043e7349046e0e2aec977c24be106925ed6"
|
||||
integrity sha512-AWje4bzqO9RUn3sdnM5N8n4ZJ0BqCc/kqFJvpOI5/EVkINXui0yuvU7NDCEF//+WaxHuNay2uOHxA4+tq1P3cg==
|
||||
|
||||
yn@3.1.1:
|
||||
version "3.1.1"
|
||||
|
||||
Reference in New Issue
Block a user