Compare commits

...

73 Commits

Author SHA1 Message Date
Joe Previte
911af4075f chore(release): bump version to 3.11.1 2021-08-06 12:17:30 -07:00
G r e y
73380379da chore(ci): replace playwright action (#3910) 2021-08-06 10:53:28 -07:00
Joe Previte
f75edc26b7 Merge pull request #3895 from cdr/jsjoeio-fix-webview-uri
fix(lib/vscode): patch authority in asWebviewUri
2021-08-05 16:47:35 -07:00
Joe Previte
99503fb546 fix(lib/vscode): patch authority in asWebviewUri
We do this because resources in webviews don't load properly
when the port is used in the resource uri.

We're not sure why this is happening but adding this fix
to get webviews working like before.
2021-08-05 16:26:05 -07:00
Joe Previte
56f0c4e193 Merge pull request #3899 from cdr/jsjoeio-fix-tar
chore: bump tar with resolutions
2021-08-04 12:45:41 -07:00
Joe Previte
dbb8cfb315 chore: bump tar with resolutions 2021-08-04 12:28:03 -07:00
Joe Previte
570cb69832 docs: note about installation logs to bug report 2021-08-03 18:37:13 -04:00
Renovate Bot
379486ac38 fix(deps): update dependency ws to v8 2021-08-03 11:14:49 -04:00
Asher
afb8662d4d Query artifacts by branch name (#3881)
This way workflows will still work even if there have been enough runs
to push the version branch run off the first page.
2021-07-30 18:32:22 +00:00
Asher
d9df02e807 Remove Dependabot (#3880)
We use Renovate now.
2021-07-30 11:03:48 -07:00
Joe Previte
ff3b188864 Merge pull request #3858 from cdr/jsjoeio-add-proxy-test
feat: add more tests for proxy.ts
2021-07-29 15:33:17 -07:00
Joe Previte
9137816e33 feat: add getAvailablePort helper function 2021-07-29 15:17:04 -07:00
Joe Previte
42cfa4a7ca feat: add tests for proxy 2021-07-29 15:16:28 -07:00
Joe Previte
7e43f7d6b0 Merge pull request #3866 from cdr/jsjoeio-reorg-test-files
refactor: clean up test file structure
2021-07-29 15:14:37 -07:00
Akash Satheesan
93c89ba0e8 fix(ci): build+push image in release flow (#3838) 2021-07-29 23:31:46 +05:30
G r e y
0283c35225 docs(install): fix link to helm readme (#3869) 2021-07-29 09:54:33 -07:00
Joe Previte
7a6ec202ba refactor: match /test/unit structure to /src 2021-07-29 09:48:40 -07:00
Joe Previte
7a5c457209 Merge pull request #3865 from cdr/renovate/minor-dependency-updates
chore(deps): update minor dependency updates
2021-07-27 15:46:39 -07:00
Renovate Bot
16f2bbd007 chore(deps): update minor dependency updates 2021-07-27 21:55:34 +00:00
Joe Previte
36be0b724d Merge pull request #3862 from cdr/dependabot/npm_and_yarn/typescript-eslint/parser-4.28.5
chore(deps-dev): bump @typescript-eslint/parser from 4.28.4 to 4.28.5
2021-07-27 09:52:30 -07:00
Joe Previte
18b1776cf0 Merge pull request #3861 from cdr/dependabot/npm_and_yarn/yarn-1.22.11
chore(deps): bump yarn from 1.22.10 to 1.22.11
2021-07-27 09:51:53 -07:00
Joe Previte
56ba22f142 Merge pull request #3863 from cdr/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-4.28.5
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 4.28.4 to 4.28.5
2021-07-27 09:51:24 -07:00
dependabot[bot]
e442542c5e chore(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.28.4 to 4.28.5.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.28.5/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 11:02:55 +00:00
dependabot[bot]
46e7d7ae7c chore(deps-dev): bump @typescript-eslint/parser from 4.28.4 to 4.28.5
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.28.4 to 4.28.5.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.28.5/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 11:02:35 +00:00
dependabot[bot]
396e2574df chore(deps): bump yarn from 1.22.10 to 1.22.11
Bumps [yarn](https://github.com/yarnpkg/yarn) from 1.22.10 to 1.22.11.
- [Release notes](https://github.com/yarnpkg/yarn/releases)
- [Changelog](https://github.com/yarnpkg/yarn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yarnpkg/yarn/compare/1.22.10...1.22.11)

---
updated-dependencies:
- dependency-name: yarn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 11:02:17 +00:00
Joe Previte
6d928a0666 Merge pull request #3846 from cdr/jsjoeio-test-should-enable-proxy
feat: add tests for shouldEnableProxy
2021-07-26 11:38:09 -07:00
Joe Previte
85d8c14b92 refactor: use Teffen's solution for useEnv 2021-07-26 11:21:30 -07:00
Joe Previte
3969a3990a Merge pull request #3840 from cdr/jsjoeio-uninstall-docs
docs(install): add uninstall instructions
2021-07-26 11:11:36 -07:00
Joe Previte
162f70ac1a docs(install): add uninstall instructions 2021-07-26 10:55:08 -07:00
Joe Previte
5b5a1f4f97 Merge pull request #3829 from cuining/main
Fix "serviceWorker.js" path
2021-07-26 10:25:47 -07:00
dependabot[bot]
05a97c3e75 chore(deps-dev): bump @types/semver from 7.3.7 to 7.3.8
Bumps [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) from 7.3.7 to 7.3.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 09:57:26 -04:00
dependabot[bot]
e91b910f75 chore(deps-dev): bump @types/node from 14.17.5 to 14.17.6
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.17.5 to 14.17.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 09:56:51 -04:00
Teffen Ellis
ad85573e8f Merge pull request #3839 from cdr/add-docs-manifest
chore: add docs manifest
2021-07-26 09:51:54 -04:00
cuining
4e489f19b5 Update register.test.ts 2021-07-25 14:49:19 +08:00
Joe Previte
67e9eca942 feat: add tests for shouldEnableProxy 2021-07-23 15:07:23 -07:00
Bruno
be0e5de7eb chore: fix json format 2021-07-22 19:22:53 +00:00
Bruno
8ca8762591 chore: add docs manifest 2021-07-22 19:10:24 +00:00
Joe Previte
7b8cd25c0c Merge pull request #3760 from cdr/jsjoeio-add-vscode-test
feat: add registerRequireOnSelf on function
2021-07-21 15:48:28 -07:00
Joe Previte
911cb034f5 feat: add registerRequireOnSelf on function 2021-07-21 15:30:54 -07:00
Joe Previte
670f0a152f Merge pull request #3812 from cdr/jsjoeio-fix-pathToFsPath
refactor: only accept string in pathToFsPath
2021-07-21 12:06:01 -07:00
Joe Previte
d0d739bec8 Merge pull request #3832 from cdr/jsjoeio-codecov
chore: update coverage thresholds
2021-07-21 11:34:05 -07:00
Teffen Ellis
dfc88e3e63 chore: Update dependency requirements. Fix node version manager. 2021-07-21 14:32:16 -04:00
Joe Previte
7ac015ed80 chore: increase jest coverage threshold to 60 2021-07-21 11:15:17 -07:00
Joe Previte
da4f87a7dc chore: update codecov range 40-70 2021-07-21 11:15:00 -07:00
Joe Previte
cb778d6f36 chore: turn off patch requirment for codecov 2021-07-21 11:14:00 -07:00
Joe Previte
6e33dccb40 feat: add tests for isFile 2021-07-21 11:12:00 -07:00
Joe Previte
5c61318592 refactor: only accept string in pathToFsPath
CodeQL caught a path where we were passing in req.query.path
to pathToFsPath, which may not have been a string.

So we refactored some things to ensure we only pass it a string
which also let us change the parameter type to string
instead of string | string[].
2021-07-21 11:11:59 -07:00
cuining
d71649acb4 Fix "serviceWorker.js" path 2021-07-21 19:09:02 +08:00
Joe Previte
0f451524f9 Merge pull request #3816 from cdr/dependabot/npm_and_yarn/types/ws-7.4.7
chore(deps-dev): bump @types/ws from 7.4.6 to 7.4.7
2021-07-20 11:25:38 -07:00
Katie Horne
a84dd25bdf chore: update guides.md header to Accessing Web Services 2021-07-20 13:14:57 -05:00
Joe Previte
52c3b0d9b4 Merge pull request #3815 from cdr/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-4.28.4
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 4.28.3 to 4.28.4
2021-07-20 11:07:54 -07:00
Joe Previte
597cdcb44d Merge pull request #3817 from cdr/dependabot/npm_and_yarn/typescript-eslint/parser-4.28.4
chore(deps-dev): bump @typescript-eslint/parser from 4.28.3 to 4.28.4
2021-07-20 11:07:07 -07:00
Katie Horne
9d6a154352 chore: update header from Self signed certificates to Accessing Web Services 2021-07-20 09:25:57 -05:00
dependabot[bot]
37b5631795 chore(deps-dev): bump @typescript-eslint/parser from 4.28.3 to 4.28.4
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.28.3 to 4.28.4.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.28.4/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-20 11:02:49 +00:00
dependabot[bot]
d44c31f896 chore(deps-dev): bump @types/ws from 7.4.6 to 7.4.7
Bumps [@types/ws](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ws) from 7.4.6 to 7.4.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ws)

---
updated-dependencies:
- dependency-name: "@types/ws"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-20 11:02:27 +00:00
dependabot[bot]
8e8abc4817 chore(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.28.3 to 4.28.4.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.28.4/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-20 11:02:15 +00:00
Joe Previte
475ae45853 Merge pull request #3813 from cdr/jsjoeio-upgrade-codecov-node
chore: update codecov to 3.8.3
2021-07-19 17:07:46 -07:00
Joe Previte
2d022b828d chore: update codecov to 3.8.3 2021-07-19 16:47:30 -07:00
Joe Previte
f96bcdc91e Merge pull request #3804 from cdr/dependabot/npm_and_yarn/eslint-7.31.0
chore(deps-dev): bump eslint from 7.30.0 to 7.31.0
2021-07-19 10:22:25 -07:00
dependabot[bot]
c3c57e5516 chore(deps-dev): bump eslint from 7.30.0 to 7.31.0
Bumps [eslint](https://github.com/eslint/eslint) from 7.30.0 to 7.31.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v7.30.0...v7.31.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-19 16:57:18 +00:00
Joe Previte
3946a5cf2e Merge pull request #3784 from cdr/dependabot/npm_and_yarn/proxy-agent-5.0.0
chore(deps): bump proxy-agent from 4.0.1 to 5.0.0
2021-07-19 09:54:10 -07:00
Asher
7cfd149cd3 Add "plus" verbiage back to login limits
There was some confusion with the "and" since it can be interpreted that
you can only try logging in twelve times per hour in total but actually
you get two attempts per minute and then twelve per hour on top of that.
2021-07-19 10:15:09 -05:00
Alexander Pushkov
f9f3f38578 Merge pull request #3783 from notpushkin/patch-1
Remove leftover merge conflict on the FAQ page
2021-07-19 10:08:33 -05:00
Asher
589982f027 Fix incorrect manifest build
I mistakenly thought they were for each arch but it's for the version
and latest which makes a *lot* more sense.
2021-07-16 18:25:54 -05:00
Asher
f720b63583 Fix Docker push (#3796) 2021-07-16 17:46:20 -05:00
Asher
9ef6680adc Fix incorrect version var in artifact script 2021-07-16 17:39:53 -05:00
Asher
a32df56f99 Skip Docker if already pushed 2021-07-16 17:39:52 -05:00
Asher
4cfa384bb4 Skip brew if already published 2021-07-16 17:39:51 -05:00
Asher
3c0799fa59 Skip npm publish if already published
This helps make the publish workflow idempotent.
2021-07-16 17:39:50 -05:00
Asher
8608d8ec74 Fix Docker push
It seems we need to use `docker import` with the output from `docker
buildx` rather than `docker load` like we were doing when we used
`docker save`.
2021-07-16 17:39:49 -05:00
renovate[bot]
903f8d9cc2 Merge pull request #3703 from cdr/renovate/configure 2021-07-16 10:05:18 -05:00
dependabot[bot]
edc50ec7fb chore(deps): bump proxy-agent from 4.0.1 to 5.0.0
Bumps [proxy-agent](https://github.com/TooTallNate/node-proxy-agent) from 4.0.1 to 5.0.0.
- [Release notes](https://github.com/TooTallNate/node-proxy-agent/releases)
- [Changelog](https://github.com/TooTallNate/node-proxy-agent/blob/master/History.md)
- [Commits](https://github.com/TooTallNate/node-proxy-agent/compare/4.0.1...5.0.0)

---
updated-dependencies:
- dependency-name: proxy-agent
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-15 11:02:15 +00:00
Akash Satheesan
52579f182d chore(release): bump version to 3.11.0 2021-07-15 02:45:10 +05:30
69 changed files with 1235 additions and 652 deletions

View File

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

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

View File

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

View File

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

View File

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

@@ -0,0 +1 @@
14

1
.nvmrc Symbolic link
View File

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

View File

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

View File

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

View File

@@ -20,4 +20,4 @@ version: 1.0.3
# This is the version number of the application being deployed. This version number should be
# 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

View File

@@ -1,6 +1,6 @@
# code-server
![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 3.10.2](https://img.shields.io/badge/AppVersion-3.10.2-informational?style=flat-square)
![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 3.11.1](https://img.shields.io/badge/AppVersion-3.11.1-informational?style=flat-square)
[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 | `""` | |

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
# code-server
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/cdr/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://cdr.co/join-community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/cdr/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/cdr/code-server) [![See v3.10.2 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v3.10.2%20&color=blue)](https://github.com/cdr/code-server/tree/v3.10.2/docs)
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/cdr/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://cdr.co/join-community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/cdr/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/cdr/code-server) [![See v3.11.1 docs](https://img.shields.io/static/v1?label=Docs&message=see%20v3.11.1%20&color=blue)](https://github.com/cdr/code-server/tree/v3.11.1/docs)
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

View File

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

View File

@@ -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
View 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"
}
]
}
]
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 + "/",

View File

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

View File

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

View File

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

View File

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

View File

@@ -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'", () => {

View File

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

View File

@@ -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("/")
})
})

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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(() => {

View File

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

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

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

View File

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

View File

@@ -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", () => {

View File

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

View File

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

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -44,7 +44,7 @@
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"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. */

View File

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

View File

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

View File

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

View File

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

View File

@@ -4392,10 +4392,10 @@ symbol-tree@^3.2.4:
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
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
View File

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