Compare commits

..

17 Commits

Author SHA1 Message Date
Asher
56d10d82bf Enforce Node binary permissions
In some cases it may have extra write permissions.
2023-06-21 11:23:40 -08:00
Asher
cef2aa22dc Move session server log after HTTP server logs
The indented logs technically apply to the HTTP server so move the
session server log afterward to avoid making them look like they apply
to the session server.
2023-06-21 10:59:02 -08:00
Sean Lee
b5a9ef80e7 Use unique socket per user for managing editor sessions (#6278)
Also warn if editor session manager socket cannot be created rather than failing.
2023-06-21 13:39:25 -05:00
Asher
5d3c9edce4 Release v4.14.0 2023-06-16 13:38:21 -08:00
Asher
9955cd91a4 Update Code to 1.79.1 (#6264)
Mostly just the usual shifting or changing of the surrounding context
but I did refactor the getting started block we insert because it keeps
getting mangled on each update.  Instead of shifting things around the
columns I just prepend it to the right column.

Getting 404s on some vsda module but everything seems to work 
without it and I do not see it referenced in the package.json nor a
nywhere on npmjs.com so it seems to be optional.
2023-06-15 08:00:03 -08:00
dependabot[bot]
fdeaba9581 chore: bump proxy-agent from 5.0.0 to 6.2.1 (#6247)
* chore: bump proxy-agent from 5.0.0 to 6.2.1

Bumps [proxy-agent](https://github.com/TooTallNate/proxy-agents/tree/HEAD/packages/proxy-agent) from 5.0.0 to 6.2.1.
- [Release notes](https://github.com/TooTallNate/proxy-agents/releases)
- [Changelog](https://github.com/TooTallNate/proxy-agents/blob/main/packages/proxy-agent/CHANGELOG.md)
- [Commits](https://github.com/TooTallNate/proxy-agents/commits/proxy-agent@6.2.1/packages/proxy-agent)

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

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

* Update proxy-agent usage

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Asher <ash@coder.com>
2023-06-14 14:27:15 -08:00
dependabot[bot]
40ff2e6049 chore: bump @typescript-eslint/parser from 5.57.1 to 5.59.11 (#6262)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.57.1 to 5.59.11.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.59.11/packages/parser)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 14:08:39 -08:00
dependabot[bot]
73d42f7ea0 chore: bump i18next from 22.4.6 to 22.5.1 (#6261)
Bumps [i18next](https://github.com/i18next/i18next) from 22.4.6 to 22.5.1.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v22.4.6...v22.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 13:33:51 -08:00
Sean Lee
fb73742b2b Prefer matching editor sessions when opening files. (#6191)
Signed-off-by: Sean Lee <freshdried@gmail.com>
2023-06-14 13:32:07 -08:00
Asher
ccb0d3a34f Remove unused dependency split2
This was used with now-removed `--link`.
2023-06-13 10:38:13 -08:00
dependabot[bot]
4a121edd16 chore: bump tj-actions/changed-files from 35 to 36 (#6246)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 35 to 36.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v35...v36)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-13 18:28:24 +00:00
dependabot[bot]
f6db985712 chore: bump robinraju/release-downloader from 1.7 to 1.8 (#6245)
Bumps [robinraju/release-downloader](https://github.com/robinraju/release-downloader) from 1.7 to 1.8.
- [Release notes](https://github.com/robinraju/release-downloader/releases)
- [Commits](https://github.com/robinraju/release-downloader/compare/v1.7...v1.8)

---
updated-dependencies:
- dependency-name: robinraju/release-downloader
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-13 12:47:40 -05:00
dependabot[bot]
6d00fc7f46 chore: bump typescript from 4.6.4 to 5.0.4 (#6182)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.6.4 to 5.0.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.6.4...v5.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-13 12:45:49 -05:00
Jonas
ee024f3f2d docs: mention Termux extension workarounds (#6227) 2023-05-31 15:00:58 -08:00
Simon Merschjohann
0703ef008c Allow {{host}} and {{port}} in domain proxy (#6225) 2023-05-31 16:31:30 -05:00
Asher
2109d1cf6a Add new unreleased section to changelog 2023-05-22 12:21:30 -08:00
Asher
74af05dfbe Release v4.13.0 2023-05-19 13:14:29 -08:00
34 changed files with 1221 additions and 561 deletions

View File

@@ -45,7 +45,7 @@ jobs:
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v35
uses: tj-actions/changed-files@v36
with:
files: |
docs/**
@@ -76,7 +76,7 @@ jobs:
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v35
uses: tj-actions/changed-files@v36
with:
files: |
ci/helm-chart/**
@@ -107,7 +107,7 @@ jobs:
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v35
uses: tj-actions/changed-files@v36
with:
files: |
**/*.ts
@@ -163,7 +163,7 @@ jobs:
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v35
uses: tj-actions/changed-files@v36
with:
files: |
**/*.ts

View File

@@ -36,7 +36,7 @@ jobs:
cache: "yarn"
- name: Download npm package from release artifacts
uses: robinraju/release-downloader@v1.7
uses: robinraju/release-downloader@v1.8
with:
repository: "coder/code-server"
tag: ${{ github.event.inputs.version || github.ref_name }}
@@ -184,7 +184,7 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Download release artifacts
uses: robinraju/release-downloader@v1.7
uses: robinraju/release-downloader@v1.8
with:
repository: "coder/code-server"
tag: v${{ env.VERSION }}

View File

@@ -20,6 +20,37 @@ Code v99.99.999
-->
## Unreleased
Code v1.79.2
## [4.14.0](https://github.com/coder/code-server/releases/tag/v4.14.0) - 2023-06-16
Code v1.79.2
### Added
- `--domain-proxy` now supports `{{port}}` and `{{host}}` template variables.
### Changed
- Updated to Code 1.79.2
- Files opened from an external terminal will now open in the most closely
related window rather than in the last opened window.
## [4.13.0](https://github.com/coder/code-server/releases/tag/v4.13.0) - 2023-05-19
Code v1.78.2
### Changed
- Updated to Code 1.78.2.
### Fixed
- Proxying files that contain non-ASCII characters.
- Origin check when X-Forwarded-Host contains comma-separated hosts.
## [4.12.0](https://github.com/coder/code-server/releases/tag/v4.12.0) - 2023-04-21
Code v1.77.3

View File

@@ -24,6 +24,8 @@ main() {
rsync ./ci/build/code-server.sh "$RELEASE_PATH/bin/code-server"
rsync "$node_path" "$RELEASE_PATH/lib/node"
chmod 755 "$RELEASE_PATH/lib/node"
pushd "$RELEASE_PATH"
npm install --unsafe-perm --omit=dev
popd

View File

@@ -112,7 +112,7 @@ EOF
pushd lib/vscode-reh-web-linux-x64
# Make sure Code took the version we set in the environment variable. Not
# having a version will break display languages.
if ! jq -e .commit product.json ; then
if ! jq -e .commit product.json; then
echo "'commit' is missing from product.json"
exit 1
fi

View File

@@ -15,9 +15,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.8.0
version: 3.10.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 4.12.0
appVersion: 4.14.0

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image:
repository: codercom/code-server
tag: '4.12.0'
tag: '4.14.0'
pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a

View File

@@ -8,6 +8,7 @@
- [Upgrade](#upgrade)
- [Known Issues](#known-issues)
- [Git won't work in `/sdcard`](#git-wont-work-in-sdcard)
- [Many extensions including language packs fail to install](#many-extensions-including-language-packs-fail-to-install)
- [Extra](#extra)
- [Create a new user](#create-a-new-user)
- [Install Go](#install-go)
@@ -87,6 +88,37 @@ Potential Workaround :
1. Create a soft-link from the debian-fs to your folder in `/sdcard`
2. Use git from termux (preferred)
### Many extensions including language packs fail to install
Issue: Android is not seen as a Linux environment but as a separate, unsupported platform, so code-server only allows [Web Extensions](https://code.visualstudio.com/api/extension-guides/web-extensions), refusing to download extensions that run on the server.\
Fix: None\
Potential workarounds :
Either
- Manually download extensions as `.vsix` file and install them via `Extensions: Install from VSIX...` in the Command Palette.
- Use an override to pretend the platform is Linux:
Create a JS script that patches `process.platform`:
```js
// android-as-linux.js
Object.defineProperty(process, "platform", {
get() {
return "linux"
},
})
```
Then use Node's `--require` option to make sure it is loaded before `code-server` starts:
```sh
NODE_OPTIONS="--require /path/to/android-as-linux.js" code-server
```
⚠️ Note that Android and Linux are not 100% compatible, so use these workarounds at your own risk. Extensions that have native dependencies other than Node or that directly interact with the OS might cause issues.
## Extra
### Create a new user

View File

@@ -49,7 +49,6 @@
"@types/proxy-from-env": "^1.0.1",
"@types/safe-compare": "^1.1.0",
"@types/semver": "^7.1.0",
"@types/split2": "^3.2.0",
"@types/trusted-types": "^2.0.2",
"@types/ws": "^8.5.3",
"@typescript-eslint/eslint-plugin": "^5.41.0",
@@ -64,7 +63,7 @@
"prettier": "2.8.0",
"prettier-plugin-sh": "^0.12.8",
"ts-node": "^10.0.0",
"typescript": "^4.6.2"
"typescript": "^5.0.4"
},
"resolutions": {
"ansi-regex": "^5.0.1",
@@ -99,13 +98,12 @@
"js-yaml": "^4.0.0",
"limiter": "^2.1.0",
"pem": "^1.14.2",
"proxy-agent": "^5.0.0",
"proxy-agent": "^6.2.1",
"qs": "6.11.0",
"rotating-file-stream": "^3.0.0",
"safe-buffer": "^5.1.1",
"safe-compare": "^1.1.4",
"semver": "^7.1.3",
"split2": "^4.0.0",
"ws": "^8.0.0",
"xdg-basedir": "^4.0.0"
},

View File

@@ -99,21 +99,14 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactor
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
+++ code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
@@ -274,6 +274,7 @@ export class BrowserSocketFactory implem
connect(host: string, port: number, path: string, query: string, debugLabel: string, callback: IConnectCallback): void {
const webSocketSchema = (/^https:/.test(window.location.href) ? 'wss' : 'ws');
+ path = (window.location.pathname + "/" + path).replace(/\/\/+/g, "/")
const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const errorListener = socket.onError((err) => callback(err, undefined));
socket.onOpen(() => {
@@ -282,6 +283,3 @@ export class BrowserSocketFactory implem
});
}
}
-
-
-
@@ -280,6 +280,7 @@ export class BrowserSocketFactory implem
connect({ host, port }: WebSocketRemoteConnection, path: string, query: string, debugLabel: string): Promise<ISocket> {
return new Promise<ISocket>((resolve, reject) => {
const webSocketSchema = (/^https:/.test(window.location.href) ? 'wss' : 'ws');
+ path = (window.location.pathname + "/" + path).replace(/\/\/+/g, "/")
const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const errorListener = socket.onError(reject);
socket.onOpen(() => {
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -261,7 +254,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
@@ -489,6 +489,7 @@ function doCreateUri(path: string, query
@@ -484,6 +484,7 @@ function doCreateUri(path: string, query
});
}
@@ -269,7 +262,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
return URI.parse(window.location.href).with({ path, query });
}
@@ -500,7 +501,7 @@ function doCreateUri(path: string, query
@@ -495,7 +496,7 @@ function doCreateUri(path: string, query
if (!configElement || !configElementAttribute) {
throw new Error('Missing web configuration element');
}
@@ -288,12 +281,12 @@ Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/ext
import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
-import { RemoteAuthorities } from 'vs/base/common/network';
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
import { TargetPlatform } from 'vs/platform/extensions/common/extensions';
const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource';
@@ -75,7 +74,7 @@ export abstract class AbstractExtensionR
public getExtensionGalleryResourceURL(galleryExtension: { publisher: string; name: string; version: string }, path?: string): URI | undefined {
if (this._extensionGalleryResourceUrlTemplate) {
const uri = URI.parse(format2(this._extensionGalleryResourceUrlTemplate, { publisher: galleryExtension.publisher, name: galleryExtension.name, version: galleryExtension.version, path: 'extension' }));
@@ -102,7 +101,7 @@ export abstract class AbstractExtensionR
: version,
path: 'extension'
}));
- return this._isWebExtensionResourceEndPoint(uri) ? uri.with({ scheme: RemoteAuthorities.getPreferredWebSchema() }) : uri;
+ return this._isWebExtensionResourceEndPoint(uri) ? URI.joinPath(URI.parse(window.location.href), uri.path) : uri;
}

View File

@@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -260,6 +260,11 @@ export interface IWorkbenchConstructionO
@@ -281,6 +281,11 @@ export interface IWorkbenchConstructionO
*/
readonly userDataPath?: string
@@ -28,19 +28,19 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -32,6 +32,11 @@ export interface IBrowserWorkbenchEnviro
* Options used to configure the workbench.
*/
@@ -34,6 +34,11 @@ export interface IBrowserWorkbenchEnviro
readonly options?: IWorkbenchConstructionOptions;
+
+ /**
/**
+ * Enable downloading files via menu actions.
+ */
+ readonly isEnabledFileDownloads?: boolean;
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -101,6 +106,13 @@ export class BrowserWorkbenchEnvironment
+
+ /**
* Gets whether a resolver extension is expected for the environment.
*/
readonly expectsResolverExtension: boolean;
@@ -111,6 +116,13 @@ export class BrowserWorkbenchEnvironment
return this.options.userDataPath;
}
@@ -90,29 +90,22 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,12 +7,11 @@ import { Event } from 'vs/base/common/ev
@@ -7,12 +7,12 @@ import { Event } from 'vs/base/common/ev
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, ActiveEditorCanToggleReadonlyContext } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads, ActiveEditorCanToggleReadonlyContext } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION, EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
@@ -25,6 +24,7 @@ import { IPaneCompositePartService } fro
import { Schemas } from 'vs/base/common/network';
import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess';
import { IProductService } from 'vs/platform/product/common/productService';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
export class WorkbenchContextKeysHandler extends Disposable {
private inputFocusedContext: IContextKey<boolean>;
@@ -77,7 +77,7 @@ export class WorkbenchContextKeysHandler
@@ -80,7 +80,7 @@ export class WorkbenchContextKeysHandler
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -121,7 +114,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@IProductService private readonly productService: IProductService,
@IEditorService private readonly editorService: IEditorService,
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
@@ -205,6 +205,9 @@ export class WorkbenchContextKeysHandler
@@ -210,6 +210,9 @@ export class WorkbenchContextKeysHandler
this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService);
this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));
@@ -144,7 +137,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ThemeIcon } from 'vs/base/common/themables';
@@ -485,13 +485,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
@@ -489,13 +489,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
id: DOWNLOAD_COMMAND_ID,
title: DOWNLOAD_LABEL
},

View File

@@ -21,7 +21,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -233,6 +233,9 @@ export async function setupServerService
@@ -234,6 +234,9 @@ export async function setupServerService
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
socketServer.registerChannel('extensions', channel);

View File

@@ -10,16 +10,25 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
@@ -60,7 +60,7 @@ import { GettingStartedIndexList } from
@@ -10,7 +10,7 @@ import { IInstantiationService } from 'v
import { IEditorSerializer, IEditorOpenContext } from 'vs/workbench/common/editor';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { assertIsDefined } from 'vs/base/common/types';
-import { $, addDisposableListener, append, clearNode, Dimension, reset } from 'vs/base/browser/dom';
+import { $, addDisposableListener, append, clearNode, Dimension, reset, prepend } from 'vs/base/browser/dom';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IProductService } from 'vs/platform/product/common/productService';
import { hiddenEntriesConfigurationKey, IResolvedWalkthrough, IResolvedWalkthroughStep, IWalkthroughsService } from 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService';
@@ -59,7 +59,7 @@ import { GettingStartedIndexList } from
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
-import { WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
+import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
import { OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { OpenFolderAction, OpenFileFolderAction, OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
import { Toggle } from 'vs/base/browser/ui/toggle/toggle';
@@ -817,6 +817,72 @@ export class GettingStartedPage extends
@@ -770,6 +770,72 @@ export class GettingStartedPage extends
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
);
@@ -92,62 +101,16 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
const leftColumn = $('.categories-column.categories-column-left', {},);
const rightColumn = $('.categories-column.categories-column-right', {},);
@@ -835,13 +901,23 @@ export class GettingStartedPage extends
const layoutLists = () => {
if (gettingStartedList.itemCount) {
this.container.classList.remove('noWalkthroughs');
- reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
- reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement(), featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
+ reset(rightColumn, gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
+ reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
+ }
@@ -819,6 +885,9 @@ export class GettingStartedPage extends
recentList.setLimit(5);
reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
}
else {
this.container.classList.add('noWalkthroughs');
- reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
- reset(rightColumn, featuredExtensionList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement(), featuredExtensionList.getDomElement());
+ reset(rightColumn, gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
+ reset(rightColumn, featuredExtensionList.getDomElement());
+ }
}
setTimeout(() => this.categoriesPageScrollbar?.scanDomNode(), 50);
};
@@ -849,13 +925,23 @@ export class GettingStartedPage extends
const layoutFeaturedExtension = () => {
if (featuredExtensionList.itemCount) {
this.container.classList.remove('noExtensions');
- reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
- reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement(), featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
+ reset(rightColumn, gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
+ reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
+ }
}
else {
this.container.classList.add('noExtensions');
- reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
- reset(rightColumn, gettingStartedList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement(), gettingStartedList.getDomElement());
+ reset(rightColumn, gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
+ reset(rightColumn, gettingStartedList.getDomElement());
+ }
}
setTimeout(() => this.categoriesPageScrollbar?.scanDomNode(), 50);
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ prepend(rightColumn, gettingStartedCoder)
+ }
};
featuredExtensionList.onDidChange(layoutFeaturedExtension);
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
@@ -172,7 +135,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -265,6 +265,11 @@ export interface IWorkbenchConstructionO
@@ -286,6 +286,11 @@ export interface IWorkbenchConstructionO
*/
readonly isEnabledFileDownloads?: boolean
@@ -188,19 +151,19 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -37,6 +37,11 @@ export interface IBrowserWorkbenchEnviro
* Enable downloading files via menu actions.
*/
@@ -39,6 +39,11 @@ export interface IBrowserWorkbenchEnviro
readonly isEnabledFileDownloads?: boolean;
+
+ /**
/**
+ * Enable Coder's custom getting started text.
+ */
+ readonly isEnabledCoderGettingStarted?: boolean;
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -113,6 +118,13 @@ export class BrowserWorkbenchEnvironment
+
+ /**
* Gets whether a resolver extension is expected for the environment.
*/
readonly expectsResolverExtension: boolean;
@@ -123,6 +128,13 @@ export class BrowserWorkbenchEnvironment
return this.options.isEnabledFileDownloads;
}
@@ -254,12 +217,12 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads, IsEnabledCoderGettingStarted } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads, ActiveEditorCanToggleReadonlyContext } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads, IsEnabledCoderGettingStarted, ActiveEditorCanToggleReadonlyContext } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION, EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
@@ -207,6 +207,7 @@ export class WorkbenchContextKeysHandler
@@ -212,6 +212,7 @@ export class WorkbenchContextKeysHandler
// code-server
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)

View File

@@ -176,7 +176,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
@@ -69,6 +69,7 @@ import { IndexedDB } from 'vs/base/brows
@@ -67,6 +67,7 @@ import { IndexedDB } from 'vs/base/brows
import { BrowserCredentialsService } from 'vs/workbench/services/credentials/browser/credentialsService';
import { IWorkspace } from 'vs/workbench/services/host/browser/browserHostService';
import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess';
@@ -184,7 +184,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel';
@@ -123,6 +124,9 @@ export class BrowserMain extends Disposa
@@ -127,6 +128,9 @@ export class BrowserMain extends Disposa
// Startup
const instantiationService = workbench.startup();

View File

@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -255,6 +255,11 @@ export interface IWorkbenchConstructionO
@@ -276,6 +276,11 @@ export interface IWorkbenchConstructionO
*/
readonly configurationDefaults?: Record<string, any>;
@@ -48,7 +48,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -92,7 +92,14 @@ export class BrowserWorkbenchEnvironment
@@ -102,7 +102,14 @@ export class BrowserWorkbenchEnvironment
get logFile(): URI { return joinPath(this.windowLogsPath, 'window.log'); }
@memoize

View File

@@ -74,10 +74,10 @@ Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/ext
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
-import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
import { TargetPlatform } from 'vs/platform/extensions/common/extensions';
const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource';
@@ -60,7 +59,7 @@ export abstract class AbstractExtensionR
@@ -77,7 +76,7 @@ export abstract class AbstractExtensionR
private readonly _environmentService: IEnvironmentService,
private readonly _configurationService: IConfigurationService,
) {

View File

@@ -42,17 +42,8 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
+++ code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
@@ -11,7 +11,7 @@ import { StopWatch } from 'vs/base/commo
import { URI } from 'vs/base/common/uri';
import { ILogService } from 'vs/platform/log/common/log';
import { IProductService } from 'vs/platform/product/common/productService';
-import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
+import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolvedOptions, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { getRemoteServerRootPath, parseAuthorityWithOptionalPort } from 'vs/platform/remote/common/remoteHosts';
export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService {
@@ -29,7 +29,7 @@ export class RemoteAuthorityResolverServ
constructor(
@@ -33,7 +33,7 @@ export class RemoteAuthorityResolverServ
isWorkbenchOptionsBasedResolution: boolean,
connectionToken: Promise<string> | string | undefined,
resourceUriProvider: ((uri: URI) => URI) | undefined,
- @IProductService productService: IProductService,
@@ -60,7 +51,7 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
@ILogService private readonly _logService: ILogService,
) {
super();
@@ -75,9 +75,14 @@ export class RemoteAuthorityResolverServ
@@ -84,9 +84,14 @@ export class RemoteAuthorityResolverServ
const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken);
performance.mark(`code/didResolveConnectionToken/${authorityPrefix}`);
this._logService.info(`Resolved connection token (${authorityPrefix}) after ${sw.elapsed()} ms`);
@@ -71,9 +62,9 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
+ }
const defaultPort = (/^https:/.test(window.location.href) ? 443 : 80);
const { host, port } = parseAuthorityWithOptionalPort(authority, defaultPort);
- const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken } };
+ const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken }, options };
RemoteAuthorities.set(authority, result.authority.host, result.authority.port);
- const result: ResolverResult = { authority: { authority, connectTo: new WebSocketRemoteConnection(host, port), connectionToken } };
+ const result: ResolverResult = { authority: { authority, connectTo: new WebSocketRemoteConnection(host, port), connectionToken }, options };
RemoteAuthorities.set(authority, host, port);
this._cache.set(authority, result);
this._onDidChangeConnectionData.fire();
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -92,7 +83,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
@@ -383,7 +383,7 @@ export async function createTerminalEnvi
@@ -384,7 +384,7 @@ export async function createTerminalEnvi
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
@@ -113,25 +104,26 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
interface ICredential {
service: string;
@@ -511,6 +512,38 @@ function doCreateUri(path: string, query
} : undefined,
@@ -505,6 +506,39 @@ function doCreateUri(path: string, query
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
workspaceProvider: WorkspaceProvider.create(config),
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),
- credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider() // with a remote, we don't use a local credentials provider
+ credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider(), // with a remote, we don't use a local credentials provider
- credentialsProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local credentials provider */ : new LocalStorageCredentialsProvider()
+ credentialsProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local credentials provider */ : new LocalStorageCredentialsProvider(),
+ resolveExternalUri: (uri: URI): Promise<URI> => {
+ let resolvedUri = uri
+ const localhostMatch = extractLocalHostUriMetaDataForPortMapping(resolvedUri)
+
+ if (localhostMatch && resolvedUri.authority !== location.host) {
+ if (config.productConfiguration && config.productConfiguration.proxyEndpointTemplate) {
+ resolvedUri = URI.parse(new URL(config.productConfiguration.proxyEndpointTemplate.replace('{{port}}', localhostMatch.port.toString()), window.location.href).toString())
+ const renderedTemplate = config.productConfiguration.proxyEndpointTemplate
+ .replace('{{port}}', localhostMatch.port.toString())
+ .replace('{{host}}', window.location.host)
+ resolvedUri = URI.parse(new URL(renderedTemplate, window.location.href).toString())
+ } else {
+ throw new Error(`Failed to resolve external URI: ${uri.toString()}. Could not determine base url because productConfiguration missing.`)
+ }
+ }
+
+ // If not localhost, return unmodified
+ // If not localhost, return unmodified.
+ return Promise.resolve(resolvedUri)
+ },
+ tunnelProvider: {

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
===================================================================
--- code-server.orig/lib/vscode/build/gulpfile.reh.js
+++ code-server/lib/vscode/build/gulpfile.reh.js
@@ -197,8 +197,7 @@ function packageTask(type, platform, arc
@@ -199,8 +199,7 @@ function packageTask(type, platform, arc
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }))
@@ -20,7 +20,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
const isUIExtension = (manifest) => {
@@ -237,9 +236,9 @@ function packageTask(type, platform, arc
@@ -239,9 +238,9 @@ function packageTask(type, platform, arc
.map(name => `.build/extensions/${name}/**`);
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
let version = packageJson.version;
const quality = product.quality;
@@ -394,7 +393,7 @@ function tweakProductForServerWeb(produc
@@ -387,7 +386,7 @@ function tweakProductForServerWeb(produc
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
optimizeTask,
util.rimraf(`out-vscode-${type}-min`),

View File

@@ -1,4 +1,4 @@
Store a static reference to the IPC socket
Store the IPC socket with workspace metadata.
This lets us use it to open files inside code-server from outside of
code-server.
@@ -9,6 +9,8 @@ To test this:
It should open in your existing code-server instance.
When the extension host is terminated, the socket is unregistered.
Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
@@ -18,20 +20,114 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-
+import { promises as fs } from 'fs';
+import * as os from 'os'
+import * as os from 'os';
+import * as _http from 'http';
+import * as path from 'vs/base/common/path';
import * as performance from 'vs/base/common/performance';
import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl';
import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor';
@@ -72,6 +74,10 @@ export class ExtHostExtensionService ext
if (this._initData.remote.isRemote && this._initData.remote.authority) {
const cliServer = this._instaService.createInstance(CLIServer);
process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath;
+
+ fs.writeFile(path.join(os.tmpdir(), 'vscode-ipc'), cliServer.ipcHandlePath).catch((error) => {
+ this._logService.error(error);
+ });
}
@@ -17,6 +19,7 @@ import { ExtensionRuntime } from 'vs/wor
import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer';
import { realpathSync } from 'vs/base/node/extpath';
import { ExtHostConsoleForwarder } from 'vs/workbench/api/node/extHostConsoleForwarder';
+import { IExtHostWorkspace } from '../common/extHostWorkspace';
import { ExtHostDiskFileSystemProvider } from 'vs/workbench/api/node/extHostDiskFileSystemProvider';
// Module loading tricks
class NodeModuleRequireInterceptor extends RequireInterceptor {
@@ -83,6 +86,52 @@ export class ExtHostExtensionService ext
await interceptor.install();
performance.mark('code/extHost/didInitAPI');
+ (async () => {
+ const socketPath = process.env['VSCODE_IPC_HOOK_CLI'];
+ if (!socketPath) {
+ return;
+ }
+ const workspace = this._instaService.invokeFunction((accessor) => {
+ const workspaceService = accessor.get(IExtHostWorkspace);
+ return workspaceService.workspace;
+ });
+ const entry = {
+ workspace,
+ socketPath
+ };
+ const message = JSON.stringify({entry});
+ const codeServerSocketPath = path.join(os.tmpdir(), 'code-server-ipc.sock');
+ await new Promise<void>((resolve, reject) => {
+ const opts: _http.RequestOptions = {
+ path: '/add-session',
+ socketPath: codeServerSocketPath,
+ method: 'POST',
+ headers: {
+ 'content-type': 'application/json',
+ }
+ };
+ const req = _http.request(opts, (res) => {
+ res.on('error', reject);
+ res.on('end', () => {
+ try {
+ if (res.statusCode === 200) {
+ resolve();
+ } else {
+ reject(new Error('Unexpected status code: ' + res.statusCode));
+ }
+ } catch (e: unknown) {
+ reject(e);
+ }
+ });
+ });
+ req.on('error', reject);
+ req.write(message);
+ req.end();
+ });
+ })().catch(error => {
+ this._logService.error(error);
+ });
+
// Do this when extension service exists, but extensions are not being activated yet.
const configProvider = await this._extHostConfiguration.getConfigProvider();
await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._logService, this._mainThreadTelemetryProxy, this._initData);
Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
+++ code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
@@ -3,6 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
+import * as os from 'os';
+import * as _http from 'http';
+import * as path from 'vs/base/common/path';
import * as nativeWatchdog from 'native-watchdog';
import * as net from 'net';
import * as minimist from 'minimist';
@@ -400,7 +403,28 @@ async function startExtensionHostProcess
);
// rewrite onTerminate-function to be a proper shutdown
- onTerminate = (reason: string) => extensionHostMain.terminate(reason);
+ onTerminate = (reason: string) => {
+ extensionHostMain.terminate(reason);
+
+ const socketPath = process.env['VSCODE_IPC_HOOK_CLI'];
+ if (!socketPath) {
+ return;
+ }
+ const message = JSON.stringify({socketPath});
+ const codeServerSocketPath = path.join(os.tmpdir(), 'code-server-ipc.sock');
+ const opts: _http.RequestOptions = {
+ path: '/delete-session',
+ socketPath: codeServerSocketPath,
+ method: 'POST',
+ headers: {
+ 'content-type': 'application/json',
+ 'accept': 'application/json'
+ }
+ };
+ const req = _http.request(opts);
+ req.write(message);
+ req.end();
+ };
}
startExtensionHostProcess().catch((err) => console.log(err));

View File

@@ -20,7 +20,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
import { NullPolicyService } from 'vs/platform/policy/common/policy';
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
import { LoggerService } from 'vs/platform/log/node/loggerService';
@@ -150,10 +151,13 @@ export async function setupServerService
@@ -151,10 +152,13 @@ export async function setupServerService
let oneDsAppender: ITelemetryAppender = NullAppender;
const isInternal = isInternalTelemetry(productService, configurationService);
if (supportsTelemetry(productService, environmentService)) {

View File

@@ -41,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -215,7 +215,7 @@ export class BrowserWorkbenchEnvironment
@@ -225,7 +225,7 @@ export class BrowserWorkbenchEnvironment
@memoize
get webviewExternalEndpoint(): string {

View File

@@ -9,9 +9,11 @@ import * as util from "../common/util"
import { DefaultedArgs } from "./cli"
import { disposer } from "./http"
import { isNodeJSErrnoException } from "./util"
import { DEFAULT_SOCKET_PATH, EditorSessionManager, makeEditorSessionManagerServer } from "./vscodeSocket"
import { handleUpgrade } from "./wsRouter"
type ListenOptions = Pick<DefaultedArgs, "socket-mode" | "socket" | "port" | "host">
type SocketOptions = { socket: string; "socket-mode"?: string }
type ListenOptions = DefaultedArgs | SocketOptions
export interface App extends Disposable {
/** Handles regular HTTP requests. */
@@ -20,12 +22,18 @@ export interface App extends Disposable {
wsRouter: Express
/** The underlying HTTP server. */
server: http.Server
/** Handles requests to the editor session management API. */
editorSessionManagerServer: http.Server
}
export const listen = async (server: http.Server, { host, port, socket, "socket-mode": mode }: ListenOptions) => {
if (socket) {
const isSocketOpts = (opts: ListenOptions): opts is SocketOptions => {
return !!(opts as SocketOptions).socket || !(opts as DefaultedArgs).host
}
export const listen = async (server: http.Server, opts: ListenOptions) => {
if (isSocketOpts(opts)) {
try {
await fs.unlink(socket)
await fs.unlink(opts.socket)
} catch (error: any) {
handleArgsSocketCatchError(error)
}
@@ -38,18 +46,20 @@ export const listen = async (server: http.Server, { host, port, socket, "socket-
server.on("error", (err) => util.logError(logger, "http server error", err))
resolve()
}
if (socket) {
server.listen(socket, onListen)
if (isSocketOpts(opts)) {
server.listen(opts.socket, onListen)
} else {
// [] is the correct format when using :: but Node errors with them.
server.listen(port, host.replace(/^\[|\]$/g, ""), onListen)
server.listen(opts.port, opts.host.replace(/^\[|\]$/g, ""), onListen)
}
})
// NOTE@jsjoeio: we need to chmod after the server is finished
// listening. Otherwise, the socket may not have been created yet.
if (socket && mode) {
await fs.chmod(socket, mode)
if (isSocketOpts(opts)) {
if (opts["socket-mode"]) {
await fs.chmod(opts.socket, opts["socket-mode"])
}
}
}
@@ -70,14 +80,22 @@ export const createApp = async (args: DefaultedArgs): Promise<App> => {
)
: http.createServer(router)
const dispose = disposer(server)
const disposeServer = disposer(server)
await listen(server, args)
const wsRouter = express()
handleUpgrade(wsRouter, server)
return { router, wsRouter, server, dispose }
const editorSessionManager = new EditorSessionManager()
const editorSessionManagerServer = await makeEditorSessionManagerServer(DEFAULT_SOCKET_PATH, editorSessionManager)
const disposeEditorSessionManagerServer = disposer(editorSessionManagerServer)
const dispose = async () => {
await Promise.all([disposeServer(), disposeEditorSessionManagerServer()])
}
return { router, wsRouter, server, dispose, editorSessionManagerServer }
}
/**

View File

@@ -3,17 +3,8 @@ import { promises as fs } from "fs"
import { load } from "js-yaml"
import * as os from "os"
import * as path from "path"
import {
canConnect,
generateCertificate,
generatePassword,
humanPath,
paths,
isNodeJSErrnoException,
splitOnFirstEquals,
} from "./util"
const DEFAULT_SOCKET_PATH = path.join(os.tmpdir(), "vscode-ipc")
import { generateCertificate, generatePassword, humanPath, paths, splitOnFirstEquals } from "./util"
import { DEFAULT_SOCKET_PATH, EditorSessionManagerClient } from "./vscodeSocket"
export enum Feature {
// No current experimental features!
@@ -574,14 +565,24 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
// Filter duplicate proxy domains and remove any leading `*.`.
const proxyDomains = new Set((args["proxy-domain"] || []).map((d) => d.replace(/^\*\./, "")))
args["proxy-domain"] = Array.from(proxyDomains)
if (args["proxy-domain"].length > 0 && !process.env.VSCODE_PROXY_URI) {
process.env.VSCODE_PROXY_URI = `{{port}}.${args["proxy-domain"][0]}`
const finalProxies = []
for (const proxyDomain of proxyDomains) {
if (!proxyDomain.includes("{{port}}")) {
finalProxies.push("{{port}}." + proxyDomain)
} else {
finalProxies.push(proxyDomain)
}
}
if (typeof args._ === "undefined") {
args._ = []
// all proxies are of format anyprefix-{{port}}-anysuffix.{{host}}, where {{host}} is optional
// e.g. code-8080.domain.tld would match for code-{{port}}.domain.tld and code-{{port}}.{{host}}
if (finalProxies.length > 0 && !process.env.VSCODE_PROXY_URI) {
process.env.VSCODE_PROXY_URI = `//${finalProxies[0]}`
}
args["proxy-domain"] = finalProxies
args._ = getResolvedPathsFromArgs(args)
return {
...args,
@@ -590,6 +591,10 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
} as DefaultedArgs // TODO: Technically no guarantee this is fulfilled.
}
export function getResolvedPathsFromArgs(args: UserProvidedArgs): string[] {
return (args._ ?? []).map((p) => path.resolve(p))
}
/**
* Helper function to return the default config file.
*
@@ -729,27 +734,6 @@ function bindAddrFromAllSources(...argsConfig: UserProvidedArgs[]): Addr {
return addr
}
/**
* Reads the socketPath based on path passed in.
*
* The one usually passed in is the DEFAULT_SOCKET_PATH.
*
* If it can't read the path, it throws an error and returns undefined.
*/
export async function readSocketPath(path: string): Promise<string | undefined> {
try {
return await fs.readFile(path, "utf8")
} catch (error) {
// If it doesn't exist, we don't care.
// But if it fails for some reason, we should throw.
// We want to surface that to the user.
if (!isNodeJSErrnoException(error) || error.code !== "ENOENT") {
throw error
}
}
return undefined
}
/**
* Determine if it looks like the user is trying to open a file or folder in an
* existing instance. The arguments here should be the arguments the user
@@ -762,6 +746,14 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
return process.env.VSCODE_IPC_HOOK_CLI
}
const paths = getResolvedPathsFromArgs(args)
const client = new EditorSessionManagerClient(DEFAULT_SOCKET_PATH)
// If we can't connect to the socket then there's no existing instance.
if (!(await client.canConnect())) {
return undefined
}
// If these flags are set then assume the user is trying to open in an
// existing instance since these flags have no effect otherwise.
const openInFlagCount = ["reuse-window", "new-window"].reduce((prev, cur) => {
@@ -769,7 +761,7 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
}, 0)
if (openInFlagCount > 0) {
logger.debug("Found --reuse-window or --new-window")
return readSocketPath(DEFAULT_SOCKET_PATH)
return await client.getConnectedSocketPath(paths[0])
}
// It's possible the user is trying to spawn another instance of code-server.
@@ -778,8 +770,8 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
// 2. That a file or directory was passed.
// 3. That the socket is active.
if (Object.keys(args).length === 1 && typeof args._ !== "undefined" && args._.length > 0) {
const socketPath = await readSocketPath(DEFAULT_SOCKET_PATH)
if (socketPath && (await canConnect(socketPath))) {
const socketPath = await client.getConnectedSocketPath(paths[0])
if (socketPath) {
logger.debug("Found existing code-server socket")
return socketPath
}

View File

@@ -373,7 +373,7 @@ export function authenticateOrigin(req: express.Request): void {
/**
* Get the host from headers. It will be trimmed and lowercased.
*/
function getHost(req: express.Request): string | undefined {
export function getHost(req: express.Request): string | undefined {
// Honor Forwarded if present.
const forwardedRaw = getFirstHeader(req, "forwarded")
if (forwardedRaw) {

View File

@@ -1,7 +1,6 @@
import { field, logger } from "@coder/logger"
import http from "http"
import * as os from "os"
import path from "path"
import { Disposable } from "../common/emitter"
import { plural } from "../common/util"
import { createApp, ensureAddress } from "./app"
@@ -70,9 +69,8 @@ export const openInExistingInstance = async (args: DefaultedArgs, socketPath: st
forceNewWindow: args["new-window"],
gotoLineMode: true,
}
const paths = args._ || []
for (let i = 0; i < paths.length; i++) {
const fp = path.resolve(paths[i])
for (let i = 0; i < args._.length; i++) {
const fp = args._[i]
if (await isDirectory(fp)) {
pipeArgs.folderURIs.push(fp)
} else {
@@ -127,7 +125,6 @@ export const runCodeServer = async (
logger.info(`Using config file ${humanPath(os.homedir(), args.config)}`)
logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
if (args.auth === AuthType.Password) {
logger.info(" - Authentication is enabled")
if (args.usingEnvPassword) {
@@ -149,7 +146,15 @@ export const runCodeServer = async (
if (args["proxy-domain"].length > 0) {
logger.info(` - ${plural(args["proxy-domain"].length, "Proxying the following domain")}:`)
args["proxy-domain"].forEach((domain) => logger.info(` - *.${domain}`))
args["proxy-domain"].forEach((domain) => logger.info(` - ${domain}`))
}
if (process.env.VSCODE_PROXY_URI) {
logger.info(`Using proxy URI in PORTS tab: ${process.env.VSCODE_PROXY_URI}`)
}
const sessionServerAddress = app.editorSessionManagerServer.address()
if (sessionServerAddress) {
logger.info(`Session server listening on ${sessionServerAddress.toString()}`)
}
if (args.enable && args.enable.length > 0) {

View File

@@ -1,34 +1,56 @@
import { Request, Router } from "express"
import { HttpCode, HttpError } from "../../common/http"
import { authenticated, ensureAuthenticated, ensureOrigin, redirect, self } from "../http"
import { getHost, authenticated, ensureAuthenticated, ensureOrigin, redirect, self } from "../http"
import { proxy } from "../proxy"
import { Router as WsRouter } from "../wsRouter"
export const router = Router()
const proxyDomainToRegex = (matchString: string): RegExp => {
const escapedMatchString = matchString.replace(/[.*+?^$()|[\]\\]/g, "\\$&")
// Replace {{port}} with a regex group to capture the port
// Replace {{host}} with .+ to allow any host match (so rely on DNS record here)
let regexString = escapedMatchString.replace("{{port}}", "(\\d+)")
regexString = regexString.replace("{{host}}", ".+")
regexString = regexString.replace(/[{}]/g, "\\$&") //replace any '{}' that might be left
return new RegExp("^" + regexString + "$")
}
let proxyRegexes: RegExp[] = []
const proxyDomainsToRegex = (proxyDomains: string[]): RegExp[] => {
if (proxyDomains.length !== proxyRegexes.length) {
proxyRegexes = proxyDomains.map(proxyDomainToRegex)
}
return proxyRegexes
}
/**
* Return the port if the request should be proxied. Anything that ends in a
* proxy domain and has a *single* subdomain should be proxied. Anything else
* should return `undefined` and will be handled as normal.
* Return the port if the request should be proxied.
*
* The proxy-domain should be of format anyprefix-{{port}}-anysuffix.{{host}}, where {{host}} is optional
* e.g. code-8080.domain.tld would match for code-{{port}}.domain.tld and code-{{port}}.{{host}}.
*
* For example if `coder.com` is specified `8080.coder.com` will be proxied
* but `8080.test.coder.com` and `test.8080.coder.com` will not.
*/
const maybeProxy = (req: Request): string | undefined => {
// Split into parts.
const host = req.headers.host || ""
const idx = host.indexOf(":")
const domain = idx !== -1 ? host.substring(0, idx) : host
const parts = domain.split(".")
// There must be an exact match.
const port = parts.shift()
const proxyDomain = parts.join(".")
if (!port || !req.args["proxy-domain"].includes(proxyDomain)) {
const reqDomain = getHost(req)
if (reqDomain === undefined) {
return undefined
}
return port
const regexs = proxyDomainsToRegex(req.args["proxy-domain"])
for (const regex of regexs) {
const match = reqDomain.match(regex)
if (match) {
return match[1] // match[1] contains the port
}
}
return undefined
}
router.all("*", async (req, res, next) => {

View File

@@ -1,7 +1,7 @@
import { field, logger } from "@coder/logger"
import * as http from "http"
import * as https from "https"
import ProxyAgent from "proxy-agent"
import { ProxyAgent } from "proxy-agent"
import * as semver from "semver"
import * as url from "url"
import { httpProxyUri, version } from "./constants"
@@ -104,7 +104,9 @@ export class UpdateProvider {
const request = (uri: string): void => {
logger.debug("Making request", field("uri", uri))
const isHttps = uri.startsWith("https")
const agent = httpProxyUri ? new ProxyAgent(httpProxyUri) : undefined
const agent = new ProxyAgent({
getProxyForUrl: () => httpProxyUri || "",
})
const httpx = isHttps ? https : http
const client = httpx.get(uri, { headers: { "User-Agent": "code-server" }, agent }, (response) => {
if (!response.statusCode || response.statusCode < 200 || response.statusCode >= 400) {

209
src/node/vscodeSocket.ts Normal file
View File

@@ -0,0 +1,209 @@
import { logger } from "@coder/logger"
import express from "express"
import * as http from "http"
import * as path from "path"
import { HttpCode } from "../common/http"
import { listen } from "./app"
import { canConnect, paths } from "./util"
// Socket path of the daemonized code-server instance.
export const DEFAULT_SOCKET_PATH = path.join(paths.data, `code-server-ipc.sock`)
export interface EditorSessionEntry {
workspace: {
id: string
folders: {
uri: {
path: string
}
}[]
}
socketPath: string
}
interface DeleteSessionRequest {
socketPath: string
}
interface AddSessionRequest {
entry: EditorSessionEntry
}
interface GetSessionResponse {
socketPath?: string
}
export async function makeEditorSessionManagerServer(
codeServerSocketPath: string,
editorSessionManager: EditorSessionManager,
): Promise<http.Server> {
const router = express()
// eslint-disable-next-line import/no-named-as-default-member
router.use(express.json())
router.get("/session", async (req, res) => {
const filePath = req.query.filePath as string
if (!filePath) {
res.status(HttpCode.BadRequest).send("filePath is required")
return
}
try {
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
const response: GetSessionResponse = { socketPath }
res.json(response)
} catch (error: unknown) {
res.status(HttpCode.ServerError).send(error)
}
})
router.post("/add-session", async (req, res) => {
const request = req.body as AddSessionRequest
if (!request.entry) {
res.status(400).send("entry is required")
}
editorSessionManager.addSession(request.entry)
res.status(200).send()
})
router.post("/delete-session", async (req, res) => {
const request = req.body as DeleteSessionRequest
if (!request.socketPath) {
res.status(400).send("socketPath is required")
}
editorSessionManager.deleteSession(request.socketPath)
res.status(200).send()
})
const server = http.createServer(router)
try {
await listen(server, { socket: codeServerSocketPath })
} catch (e) {
logger.warn(`Could not create socket at ${codeServerSocketPath}`)
}
return server
}
export class EditorSessionManager {
// Map from socket path to EditorSessionEntry.
private entries = new Map<string, EditorSessionEntry>()
addSession(entry: EditorSessionEntry): void {
logger.debug(`Adding session to session registry: ${entry.socketPath}`)
this.entries.set(entry.socketPath, entry)
}
getCandidatesForFile(filePath: string): EditorSessionEntry[] {
const matchCheckResults = new Map<string, boolean>()
const checkMatch = (entry: EditorSessionEntry): boolean => {
if (matchCheckResults.has(entry.socketPath)) {
return matchCheckResults.get(entry.socketPath)!
}
const result = entry.workspace.folders.some((folder) => filePath.startsWith(folder.uri.path + path.sep))
matchCheckResults.set(entry.socketPath, result)
return result
}
return Array.from(this.entries.values())
.reverse() // Most recently registered first.
.sort((a, b) => {
// Matches first.
const aMatch = checkMatch(a)
const bMatch = checkMatch(b)
if (aMatch === bMatch) {
return 0
}
if (aMatch) {
return -1
}
return 1
})
}
deleteSession(socketPath: string): void {
logger.debug(`Deleting session from session registry: ${socketPath}`)
this.entries.delete(socketPath)
}
/**
* Returns the best socket path that we can connect to.
* We also delete any sockets that we can't connect to.
*/
async getConnectedSocketPath(filePath: string): Promise<string | undefined> {
const candidates = this.getCandidatesForFile(filePath)
let match: EditorSessionEntry | undefined = undefined
for (const candidate of candidates) {
if (await canConnect(candidate.socketPath)) {
match = candidate
break
}
this.deleteSession(candidate.socketPath)
}
return match?.socketPath
}
}
export class EditorSessionManagerClient {
constructor(private codeServerSocketPath: string) {}
async canConnect() {
return canConnect(this.codeServerSocketPath)
}
async getConnectedSocketPath(filePath: string): Promise<string | undefined> {
const response = await new Promise<GetSessionResponse>((resolve, reject) => {
const opts = {
path: "/session?filePath=" + encodeURIComponent(filePath),
socketPath: this.codeServerSocketPath,
method: "GET",
}
const req = http.request(opts, (res) => {
let rawData = ""
res.setEncoding("utf8")
res.on("data", (chunk) => {
rawData += chunk
})
res.on("end", () => {
try {
const obj = JSON.parse(rawData)
if (res.statusCode === 200) {
resolve(obj)
} else {
reject(new Error("Unexpected status code: " + res.statusCode))
}
} catch (e: unknown) {
reject(e)
}
})
})
req.on("error", reject)
req.end()
})
return response.socketPath
}
// Currently only used for tests.
async addSession(request: AddSessionRequest): Promise<void> {
await new Promise<void>((resolve, reject) => {
const opts = {
path: "/add-session",
socketPath: this.codeServerSocketPath,
method: "POST",
headers: {
"content-type": "application/json",
accept: "application/json",
},
}
const req = http.request(opts, () => {
resolve()
})
req.on("error", reject)
req.write(JSON.stringify(request))
req.end()
})
}
}

View File

@@ -17,7 +17,7 @@ describe("createApp", () => {
beforeAll(async () => {
mockLogger()
const testName = "unlink-socket"
const testName = "app"
await clean(testName)
tmpDirPath = await tmpdir(testName)
tmpFilePath = path.join(tmpDirPath, "unlink-socket-file")
@@ -103,7 +103,7 @@ describe("createApp", () => {
const app = await createApp(defaultArgs)
expect(unlinkSpy).toHaveBeenCalledTimes(1)
expect(unlinkSpy).toHaveBeenCalledWith(tmpFilePath)
app.dispose()
})

View File

@@ -1,14 +1,11 @@
import { Level, logger } from "@coder/logger"
import { promises as fs } from "fs"
import * as net from "net"
import * as os from "os"
import * as path from "path"
import {
UserProvidedArgs,
bindAddrFromArgs,
defaultConfigFile,
parse,
readSocketPath,
setDefaults,
shouldOpenInExistingInstance,
toCodeArgs,
@@ -20,7 +17,13 @@ import {
} from "../../../src/node/cli"
import { shouldSpawnCliProcess } from "../../../src/node/main"
import { generatePassword, paths } from "../../../src/node/util"
import { clean, useEnv, tmpdir } from "../../utils/helpers"
import {
DEFAULT_SOCKET_PATH,
EditorSessionManager,
EditorSessionManagerClient,
makeEditorSessionManagerServer,
} from "../../../src/node/vscodeSocket"
import { clean, useEnv, tmpdir, listenOn } from "../../utils/helpers"
// The parser should not set any defaults so the caller can determine what
// values the user actually set. These are only set after explicitly calling
@@ -413,7 +416,7 @@ describe("parser", () => {
const defaultArgs = await setDefaults(args)
expect(defaultArgs).toEqual({
...defaults,
"proxy-domain": ["coder.com", "coder.org"],
"proxy-domain": ["{{port}}.coder.com", "{{port}}.coder.org"],
})
})
it("should allow '=,$/' in strings", async () => {
@@ -466,14 +469,14 @@ describe("parser", () => {
it("should set proxy uri", async () => {
await setDefaults(parse(["--proxy-domain", "coder.org"]))
expect(process.env.VSCODE_PROXY_URI).toEqual("{{port}}.coder.org")
expect(process.env.VSCODE_PROXY_URI).toEqual("//{{port}}.coder.org")
})
it("should set proxy uri to first domain", async () => {
await setDefaults(
parse(["--proxy-domain", "*.coder.com", "--proxy-domain", "coder.com", "--proxy-domain", "coder.org"]),
)
expect(process.env.VSCODE_PROXY_URI).toEqual("{{port}}.coder.com")
expect(process.env.VSCODE_PROXY_URI).toEqual("//{{port}}.coder.com")
})
it("should not override existing proxy uri", async () => {
@@ -487,7 +490,7 @@ describe("parser", () => {
describe("cli", () => {
const testName = "cli"
const vscodeIpcPath = path.join(os.tmpdir(), "vscode-ipc")
let tmpDirPath: string
beforeAll(async () => {
await clean(testName)
@@ -495,7 +498,7 @@ describe("cli", () => {
beforeEach(async () => {
delete process.env.VSCODE_IPC_HOOK_CLI
await fs.rm(vscodeIpcPath, { force: true, recursive: true })
tmpDirPath = await tmpdir(testName)
})
it("should use existing if inside code-server", async () => {
@@ -509,54 +512,152 @@ describe("cli", () => {
})
it("should use existing if --reuse-window is set", async () => {
const server = await makeEditorSessionManagerServer(DEFAULT_SOCKET_PATH, new EditorSessionManager())
const args: UserProvidedArgs = {}
args["reuse-window"] = true
await expect(shouldOpenInExistingInstance(args)).resolves.toStrictEqual(undefined)
await fs.writeFile(vscodeIpcPath, "test")
await expect(shouldOpenInExistingInstance(args)).resolves.toStrictEqual("test")
const socketPath = path.join(tmpDirPath, "socket")
const client = new EditorSessionManagerClient(DEFAULT_SOCKET_PATH)
await client.addSession({
entry: {
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath,
},
})
const vscodeSockets = listenOn(socketPath)
await expect(shouldOpenInExistingInstance(args)).resolves.toStrictEqual(socketPath)
args.port = 8081
await expect(shouldOpenInExistingInstance(args)).resolves.toStrictEqual("test")
await expect(shouldOpenInExistingInstance(args)).resolves.toStrictEqual(socketPath)
server.close()
vscodeSockets.close()
})
it("should use existing if --new-window is set", async () => {
const server = await makeEditorSessionManagerServer(DEFAULT_SOCKET_PATH, new EditorSessionManager())
const args: UserProvidedArgs = {}
args["new-window"] = true
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
await expect(shouldOpenInExistingInstance(args)).resolves.toStrictEqual(undefined)
await fs.writeFile(vscodeIpcPath, "test")
expect(await shouldOpenInExistingInstance(args)).toStrictEqual("test")
const socketPath = path.join(tmpDirPath, "socket")
const client = new EditorSessionManagerClient(DEFAULT_SOCKET_PATH)
await client.addSession({
entry: {
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath,
},
})
const vscodeSockets = listenOn(socketPath)
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(socketPath)
args.port = 8081
expect(await shouldOpenInExistingInstance(args)).toStrictEqual("test")
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(socketPath)
server.close()
vscodeSockets.close()
})
it("should use existing if no unrelated flags are set, has positional, and socket is active", async () => {
const server = await makeEditorSessionManagerServer(DEFAULT_SOCKET_PATH, new EditorSessionManager())
const args: UserProvidedArgs = {}
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
args._ = ["./file"]
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
const testDir = await tmpdir(testName)
const socketPath = path.join(testDir, "socket")
await fs.writeFile(vscodeIpcPath, socketPath)
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
await new Promise((resolve) => {
const server = net.createServer(() => {
// Close after getting the first connection.
server.close()
})
server.once("listening", () => resolve(server))
server.listen(socketPath)
const client = new EditorSessionManagerClient(DEFAULT_SOCKET_PATH)
const socketPath = path.join(tmpDirPath, "socket")
await client.addSession({
entry: {
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath,
},
})
const vscodeSockets = listenOn(socketPath)
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(socketPath)
args.port = 8081
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
server.close()
vscodeSockets.close()
})
it("should prefer matching sessions for only the first path", async () => {
const server = await makeEditorSessionManagerServer(DEFAULT_SOCKET_PATH, new EditorSessionManager())
const client = new EditorSessionManagerClient(DEFAULT_SOCKET_PATH)
await client.addSession({
entry: {
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa.sock`,
},
})
await client.addSession({
entry: {
workspace: {
id: "bbb",
folders: [
{
uri: {
path: "/bbb",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-bbb.sock`,
},
})
listenOn(`${tmpDirPath}/vscode-ipc-aaa.sock`, `${tmpDirPath}/vscode-ipc-bbb.sock`)
const args: UserProvidedArgs = {}
args._ = ["/aaa/file", "/bbb/file"]
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(`${tmpDirPath}/vscode-ipc-aaa.sock`)
server.close()
})
})
@@ -729,44 +830,6 @@ cert: false`)
})
})
describe("readSocketPath", () => {
const fileContents = "readSocketPath file contents"
let tmpDirPath: string
let tmpFilePath: string
const testName = "readSocketPath"
beforeAll(async () => {
await clean(testName)
})
beforeEach(async () => {
tmpDirPath = await tmpdir(testName)
tmpFilePath = path.join(tmpDirPath, "readSocketPath.txt")
await fs.writeFile(tmpFilePath, fileContents)
})
it("should throw an error if it can't read the file", async () => {
// TODO@jsjoeio - implement
// Test it on a directory.... ESDIR
// TODO@jsjoeio - implement
expect(() => readSocketPath(tmpDirPath)).rejects.toThrow("EISDIR")
})
it("should return undefined if it can't read the file", async () => {
// TODO@jsjoeio - implement
const socketPath = await readSocketPath(path.join(tmpDirPath, "not-a-file"))
expect(socketPath).toBeUndefined()
})
it("should return the file contents", async () => {
const contents = await readSocketPath(tmpFilePath)
expect(contents).toBe(fileContents)
})
it("should return the same file contents for two different calls", async () => {
const contents1 = await readSocketPath(tmpFilePath)
const contents2 = await readSocketPath(tmpFilePath)
expect(contents2).toBe(contents1)
})
})
describe("toCodeArgs", () => {
const vscodeDefaults = {
...defaults,

View File

@@ -0,0 +1,288 @@
import { logger } from "@coder/logger"
import * as app from "../../../src/node/app"
import { paths } from "../../../src/node/util"
import {
DEFAULT_SOCKET_PATH,
EditorSessionManager,
makeEditorSessionManagerServer,
} from "../../../src/node/vscodeSocket"
import { clean, tmpdir, listenOn, mockLogger } from "../../utils/helpers"
describe("DEFAULT_SOCKET_PATH", () => {
it("should be a unique path per user", () => {
expect(DEFAULT_SOCKET_PATH.startsWith(paths.data)).toBe(true)
})
})
describe("makeEditorSessionManagerServer", () => {
let tmpDirPath: string
const testName = "mesms"
beforeAll(async () => {
jest.clearAllMocks()
mockLogger()
await clean(testName)
})
afterAll(() => {
jest.resetModules()
})
beforeEach(async () => {
tmpDirPath = await tmpdir(testName)
})
it("warns if socket cannot be created", async () => {
jest.spyOn(app, "listen").mockImplementation(() => {
throw new Error()
})
const server = await makeEditorSessionManagerServer(
`${tmpDirPath}/code-server-ipc.sock`,
new EditorSessionManager(),
)
expect(logger.warn).toHaveBeenCalledWith(`Could not create socket at ${tmpDirPath}/code-server-ipc.sock`)
server.close()
})
})
describe("EditorSessionManager", () => {
let tmpDirPath: string
const testName = "esm"
beforeAll(async () => {
await clean(testName)
})
beforeEach(async () => {
tmpDirPath = await tmpdir(testName)
})
describe("getCandidatesForFile", () => {
it("should prefer the last added socket path for a matching path", async () => {
const manager = new EditorSessionManager()
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa-1.sock`,
})
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa-2.sock`,
})
manager.addSession({
workspace: {
id: "bbb",
folders: [
{
uri: {
path: "/bbb",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-bbb.sock`,
})
const socketPaths = manager.getCandidatesForFile("/aaa/some-file:1:1")
expect(socketPaths.map((x) => x.socketPath)).toEqual([
// Matches
`${tmpDirPath}/vscode-ipc-aaa-2.sock`,
`${tmpDirPath}/vscode-ipc-aaa-1.sock`,
// Non-matches
`${tmpDirPath}/vscode-ipc-bbb.sock`,
])
})
it("should return the last added socketPath if there are no matches", async () => {
const manager = new EditorSessionManager()
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa.sock`,
})
manager.addSession({
workspace: {
id: "bbb",
folders: [
{
uri: {
path: "/bbb",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-bbb.sock`,
})
const socketPaths = manager.getCandidatesForFile("/ccc/some-file:1:1")
expect(socketPaths.map((x) => x.socketPath)).toEqual([
`${tmpDirPath}/vscode-ipc-bbb.sock`,
`${tmpDirPath}/vscode-ipc-aaa.sock`,
])
})
it("does not just directly do a substring match", async () => {
const manager = new EditorSessionManager()
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa.sock`,
})
manager.addSession({
workspace: {
id: "bbb",
folders: [
{
uri: {
path: "/bbb",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-bbb.sock`,
})
const entries = manager.getCandidatesForFile("/aaaxxx/some-file:1:1")
expect(entries.map((x) => x.socketPath)).toEqual([
`${tmpDirPath}/vscode-ipc-bbb.sock`,
`${tmpDirPath}/vscode-ipc-aaa.sock`,
])
})
})
describe("getConnectedSocketPath", () => {
it("should return socket path if socket is active", async () => {
listenOn(`${tmpDirPath}/vscode-ipc-aaa.sock`).once()
const manager = new EditorSessionManager()
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa.sock`,
})
const socketPath = await manager.getConnectedSocketPath("/aaa/some-file:1:1")
expect(socketPath).toBe(`${tmpDirPath}/vscode-ipc-aaa.sock`)
})
it("should return undefined if socket is inactive", async () => {
const manager = new EditorSessionManager()
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa.sock`,
})
const socketPath = await manager.getConnectedSocketPath("/aaa/some-file:1:1")
expect(socketPath).toBeUndefined()
})
it("should return undefined given no matching active sockets", async () => {
const vscodeSockets = listenOn(`${tmpDirPath}/vscode-ipc-bbb.sock`)
const manager = new EditorSessionManager()
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa.sock`,
})
const socketPath = await manager.getConnectedSocketPath("/aaa/some-file:1:1")
expect(socketPath).toBeUndefined()
vscodeSockets.close()
})
it("should return undefined if there are no entries", async () => {
const manager = new EditorSessionManager()
const socketPath = await manager.getConnectedSocketPath("/aaa/some-file:1:1")
expect(socketPath).toBeUndefined()
})
it("should return most recently used socket path available", async () => {
listenOn(`${tmpDirPath}/vscode-ipc-aaa-1.sock`).once()
const manager = new EditorSessionManager()
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa-1.sock`,
})
manager.addSession({
workspace: {
id: "aaa",
folders: [
{
uri: {
path: "/aaa",
},
},
],
},
socketPath: `${tmpDirPath}/vscode-ipc-aaa-2.sock`,
})
const socketPath = await manager.getConnectedSocketPath("/aaa/some-file:1:1")
expect(socketPath).toBe(`${tmpDirPath}/vscode-ipc-aaa-1.sock`)
// Failed sockets should be removed from the entries.
expect((manager as any).entries.has(`${tmpDirPath}/vscode-ipc-aaa-2.sock`)).toBe(false)
})
})
})

View File

@@ -150,3 +150,52 @@ export function getMaybeProxiedPathname(url: URL): string {
return url.pathname
}
interface FakeVscodeSockets {
/* If called, closes all servers after the first connection. */
once(): FakeVscodeSockets
/* Manually close all servers. */
close(): Promise<void>
}
/**
* Creates servers for each socketPath specified.
*/
export function listenOn(...socketPaths: string[]): FakeVscodeSockets {
let once = false
const servers = socketPaths.map((socketPath) => {
const server = net.createServer(() => {
if (once) {
close()
}
})
server.listen(socketPath)
return server
})
async function close() {
await Promise.all(
servers.map(
(server) =>
new Promise<void>((resolve, reject) => {
server.close((err) => {
if (err) {
reject(err)
return
}
resolve()
})
}),
),
)
}
const fakeVscodeSockets = {
close,
once: () => {
once = true
return fakeVscodeSockets
},
}
return fakeVscodeSockets
}

380
yarn.lock
View File

@@ -173,11 +173,6 @@
traverse "^0.6.6"
unified "^9.2.2"
"@tootallnate/once@1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
"@tsconfig/node10@^1.0.7":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606"
@@ -332,13 +327,6 @@
"@types/mime" "^1"
"@types/node" "*"
"@types/split2@^3.2.0":
version "3.2.1"
resolved "https://registry.yarnpkg.com/@types/split2/-/split2-3.2.1.tgz#97c42b560a1b41064d46cd728cf1267d5755ee34"
integrity sha512-7uz3yU+LooBq4yNOzlZD9PU9/1Eu0rTD1MjQ6apOVEoHsPrMUrFw7W8XrvWtesm2vK67SBK9AyJcOXtMpl9bgQ==
dependencies:
"@types/node" "*"
"@types/trusted-types@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
@@ -378,23 +366,15 @@
tsutils "^3.21.0"
"@typescript-eslint/parser@^5.41.0":
version "5.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.57.1.tgz#af911234bd4401d09668c5faf708a0570a17a748"
integrity sha512-hlA0BLeVSA/wBPKdPGxoVr9Pp6GutGoY380FEhbVi0Ph4WNe8kLvqIRx76RSQt1lynZKfrXKs0/XeEk4zZycuA==
version "5.59.11"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.11.tgz#af7d4b7110e3068ce0b97550736de455e4250103"
integrity sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==
dependencies:
"@typescript-eslint/scope-manager" "5.57.1"
"@typescript-eslint/types" "5.57.1"
"@typescript-eslint/typescript-estree" "5.57.1"
"@typescript-eslint/scope-manager" "5.59.11"
"@typescript-eslint/types" "5.59.11"
"@typescript-eslint/typescript-estree" "5.59.11"
debug "^4.3.4"
"@typescript-eslint/scope-manager@5.57.1":
version "5.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.57.1.tgz#5d28799c0fc8b501a29ba1749d827800ef22d710"
integrity sha512-N/RrBwEUKMIYxSKl0oDK5sFVHd6VI7p9K5MyUlVYAY6dyNb/wHUqndkTd3XhpGlXgnQsBkRZuu4f9kAHghvgPw==
dependencies:
"@typescript-eslint/types" "5.57.1"
"@typescript-eslint/visitor-keys" "5.57.1"
"@typescript-eslint/scope-manager@5.59.1":
version "5.59.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz#8a20222719cebc5198618a5d44113705b51fd7fe"
@@ -403,6 +383,14 @@
"@typescript-eslint/types" "5.59.1"
"@typescript-eslint/visitor-keys" "5.59.1"
"@typescript-eslint/scope-manager@5.59.11":
version "5.59.11"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz#5d131a67a19189c42598af9fb2ea1165252001ce"
integrity sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==
dependencies:
"@typescript-eslint/types" "5.59.11"
"@typescript-eslint/visitor-keys" "5.59.11"
"@typescript-eslint/type-utils@5.59.1":
version "5.59.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz#63981d61684fd24eda2f9f08c0a47ecb000a2111"
@@ -413,28 +401,15 @@
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/types@5.57.1":
version "5.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.57.1.tgz#d9989c7a9025897ea6f0550b7036027f69e8a603"
integrity sha512-bSs4LOgyV3bJ08F5RDqO2KXqg3WAdwHCu06zOqcQ6vqbTJizyBhuh1o1ImC69X4bV2g1OJxbH71PJqiO7Y1RuA==
"@typescript-eslint/types@5.59.1":
version "5.59.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.1.tgz#03f3fedd1c044cb336ebc34cc7855f121991f41d"
integrity sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==
"@typescript-eslint/typescript-estree@5.57.1":
version "5.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.1.tgz#10d9643e503afc1ca4f5553d9bbe672ea4050b71"
integrity sha512-A2MZqD8gNT0qHKbk2wRspg7cHbCDCk2tcqt6ScCFLr5Ru8cn+TCfM786DjPhqwseiS+PrYwcXht5ztpEQ6TFTw==
dependencies:
"@typescript-eslint/types" "5.57.1"
"@typescript-eslint/visitor-keys" "5.57.1"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/types@5.59.11":
version "5.59.11"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.11.tgz#1a9018fe3c565ba6969561f2a49f330cf1fe8db1"
integrity sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==
"@typescript-eslint/typescript-estree@5.59.1":
version "5.59.1"
@@ -449,6 +424,19 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/typescript-estree@5.59.11":
version "5.59.11"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz#b2caaa31725e17c33970c1197bcd54e3c5f42b9f"
integrity sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==
dependencies:
"@typescript-eslint/types" "5.59.11"
"@typescript-eslint/visitor-keys" "5.59.11"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.59.1":
version "5.59.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.1.tgz#d89fc758ad23d2157cfae53f0b429bdf15db9473"
@@ -463,14 +451,6 @@
eslint-scope "^5.1.1"
semver "^7.3.7"
"@typescript-eslint/visitor-keys@5.57.1":
version "5.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.1.tgz#585e5fa42a9bbcd9065f334fd7c8a4ddfa7d905e"
integrity sha512-RjQrAniDU0CEk5r7iphkm731zKlFiUjvcBS2yHAg8WWqFMCaCrD0rKEVOMUyMMcbGPZ0bPp56srkGWrgfZqLRA==
dependencies:
"@typescript-eslint/types" "5.57.1"
eslint-visitor-keys "^3.3.0"
"@typescript-eslint/visitor-keys@5.59.1":
version "5.59.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz#0d96c36efb6560d7fb8eb85de10442c10d8f6058"
@@ -479,6 +459,14 @@
"@typescript-eslint/types" "5.59.1"
eslint-visitor-keys "^3.3.0"
"@typescript-eslint/visitor-keys@5.59.11":
version "5.59.11"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz#dca561ddad169dc27d62396d64f45b2d2c3ecc56"
integrity sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==
dependencies:
"@typescript-eslint/types" "5.59.11"
eslint-visitor-keys "^3.3.0"
JSONStream@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
@@ -515,13 +503,20 @@ acorn@^8.4.1, acorn@^8.7.0, acorn@^8.8.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
agent-base@6, agent-base@^6.0.0, agent-base@^6.0.2:
agent-base@6:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
dependencies:
debug "4"
agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434"
integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==
dependencies:
debug "^4.3.4"
ajv@^6.10.0, ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
@@ -668,6 +663,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
basic-ftp@^5.0.2:
version "5.0.3"
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.3.tgz#b14c0fe8111ce001ec913686434fe0c2fb461228"
integrity sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==
body-parser@1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
@@ -738,11 +738,6 @@ bytes@3.1.0:
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
bytes@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a"
integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==
call-bind@^1.0.0, call-bind@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
@@ -890,11 +885,6 @@ cookie@0.4.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
create-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
@@ -914,10 +904,10 @@ crypt@0.0.2:
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
data-uri-to-buffer@3:
version "3.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==
data-uri-to-buffer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-5.0.1.tgz#db89a9e279c2ffe74f50637a59a32fb23b3e4d7c"
integrity sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==
debug@2.6.9:
version "2.6.9"
@@ -972,15 +962,15 @@ define-properties@^1.1.4:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
degenerator@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-3.0.1.tgz#7ef78ec0c8577a544477308ddf1d2d6e88d51f5b"
integrity sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==
degenerator@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-4.0.2.tgz#55b7fb41239ee0ea7644fa3f2aba84e0adfaa40c"
integrity sha512-HKwIFvZROUMfH3qI3gBpD61BYh7q3c3GXD5UGZzoVNJwVSYgZKvYl1fRMXc9ozoTxl/VZxKJ5v/bA+19tywFiw==
dependencies:
ast-types "^0.13.2"
escodegen "^1.8.1"
esprima "^4.0.0"
vm2 "^3.9.3"
vm2 "^3.9.17"
delegates@^1.0.0:
version "1.0.0"
@@ -1546,11 +1536,6 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
file-uri-to-path@2:
version "2.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz#7b415aeba227d575851e0a5b0c640d7656403fba"
integrity sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@@ -1645,14 +1630,6 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
ftp@^0.3.10:
version "0.3.10"
resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d"
integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=
dependencies:
readable-stream "1.1.x"
xregexp "2.0.0"
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -1733,17 +1710,15 @@ get-tsconfig@^4.2.0:
resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.2.0.tgz#ff368dd7104dab47bf923404eb93838245c66543"
integrity sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==
get-uri@3:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c"
integrity sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==
get-uri@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.1.tgz#cff2ba8d456c3513a04b70c45de4dbcca5b1527c"
integrity sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==
dependencies:
"@tootallnate/once" "1"
data-uri-to-buffer "3"
debug "4"
file-uri-to-path "2"
basic-ftp "^5.0.2"
data-uri-to-buffer "^5.0.1"
debug "^4.3.4"
fs-extra "^8.1.0"
ftp "^0.3.10"
glob-parent@^5.1.2, glob-parent@^6.0.1, glob-parent@^6.0.2:
version "6.0.2"
@@ -1912,17 +1887,6 @@ http-errors@1.7.2:
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
http-errors@1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.1"
http-errors@~1.7.2:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
@@ -1934,14 +1898,13 @@ http-errors@~1.7.2:
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==
http-proxy-agent@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673"
integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==
dependencies:
"@tootallnate/once" "1"
agent-base "6"
debug "4"
agent-base "^7.1.0"
debug "^4.3.4"
http-proxy@^1.18.0:
version "1.18.1"
@@ -1957,7 +1920,7 @@ httpolyglot@^0.1.2:
resolved "https://registry.yarnpkg.com/httpolyglot/-/httpolyglot-0.1.2.tgz#e4d347fe8984a62f467d4060df527f1851f6997b"
integrity sha1-5NNH/omEpi9GfUBg31J/GFH2mXs=
https-proxy-agent@5, https-proxy-agent@^5.0.0:
https-proxy-agent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
@@ -1965,10 +1928,18 @@ https-proxy-agent@5, https-proxy-agent@^5.0.0:
agent-base "6"
debug "4"
https-proxy-agent@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz#75cb70d04811685667183b31ab158d006750418a"
integrity sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==
dependencies:
agent-base "^7.0.2"
debug "4"
i18next@^22.4.6:
version "22.4.6"
resolved "https://registry.npmmirror.com/i18next/-/i18next-22.4.6.tgz#876352c3ba81bdfedc38eeda124e2bbd05f46988"
integrity sha512-9Tm1ezxWyzV+306CIDMBbYBitC1jedQyYuuLtIv7oxjp2ohh8eyxP9xytIf+2bbQfhH784IQKPSYp+Zq9+YSbw==
version "22.5.1"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.5.1.tgz#99df0b318741a506000c243429a7352e5f44d424"
integrity sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==
dependencies:
"@babel/runtime" "^7.20.6"
@@ -2005,7 +1976,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.1:
inherits@2, inherits@2.0.4, inherits@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -2038,6 +2009,11 @@ ip@^1.1.5:
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
ip@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
@@ -2225,11 +2201,6 @@ is-wsl@^2.2.0:
dependencies:
is-docker "^2.0.0"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -2326,13 +2297,6 @@ longest-streak@^2.0.0:
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
dependencies:
yallist "^3.0.2"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -2340,10 +2304,10 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lru-cache@^7.5.1:
version "7.5.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.5.1.tgz#660a134c2c3c015aa453b03df55d2a9f0c216a0f"
integrity sha512-q1TS8IqKvcg3aScamKCHpepSrHF537Ww7nHahBOxhDu9D2YoBXAsj/7uFdZFj1xJr9LmyeJ62AdyofCHafUbIA==
lru-cache@^7.14.1, lru-cache@^7.5.1:
version "7.18.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
make-dir@^3.1.0:
version "3.1.0"
@@ -2661,7 +2625,7 @@ negotiator@0.6.2:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
netmask@^2.0.1:
netmask@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
@@ -2825,29 +2789,27 @@ p-locate@^5.0.0:
dependencies:
p-limit "^3.0.2"
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==
pac-proxy-agent@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-6.0.3.tgz#61042187093b67aa7dd05b41e4ec7c241a27c428"
integrity sha512-5Hr1KgPDoc21Vn3rsXBirwwDnF/iac1jN/zkpsOYruyT+ZgsUhUOgVwq3v9+ukjZd/yGm/0nzO1fDfl7rkGoHQ==
dependencies:
"@tootallnate/once" "1"
agent-base "6"
debug "4"
get-uri "3"
http-proxy-agent "^4.0.1"
https-proxy-agent "5"
pac-resolver "^5.0.0"
raw-body "^2.2.0"
socks-proxy-agent "5"
agent-base "^7.0.2"
debug "^4.3.4"
get-uri "^6.0.1"
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.0"
pac-resolver "^6.0.1"
socks-proxy-agent "^8.0.1"
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==
pac-resolver@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-6.0.1.tgz#319c182d3db4e6782e79519cb4dd1dda46579292"
integrity sha512-dg497MhVT7jZegPRuOScQ/z0aV/5WR0gTdRu1md+Irs9J9o+ls5jIuxjo1WfaTG+eQQkxyn5HMGvWK+w7EIBkQ==
dependencies:
degenerator "^3.0.1"
degenerator "^4.0.1"
ip "^1.1.5"
netmask "^2.0.1"
netmask "^2.0.2"
parent-module@^1.0.0:
version "1.0.1"
@@ -2978,21 +2940,21 @@ proxy-addr@~2.0.5:
forwarded "~0.1.2"
ipaddr.js "1.9.1"
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==
proxy-agent@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.2.1.tgz#062df6609a4012fd1c108974865599b61e77abde"
integrity sha512-OIbBKlRAT+ycCm6wAYIzMwPejzRtjy8F3QiDX0eKOA3e4pe3U9F/IvzcHP42bmgQxVv97juG+J8/gx+JIeCX/Q==
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 "^5.0.0"
proxy-from-env "^1.0.0"
socks-proxy-agent "^5.0.0"
agent-base "^7.0.2"
debug "^4.3.4"
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.0"
lru-cache "^7.14.1"
pac-proxy-agent "^6.0.3"
proxy-from-env "^1.1.0"
socks-proxy-agent "^8.0.1"
proxy-from-env@^1.0.0:
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
@@ -3029,26 +2991,6 @@ raw-body@2.4.0:
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-body@^2.2.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32"
integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==
dependencies:
bytes "3.1.1"
http-errors "1.8.1"
iconv-lite "0.4.24"
unpipe "1.0.0"
readable-stream@1.1.x:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
@@ -3256,11 +3198,6 @@ setprototypeof@1.1.1:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
sh-syntax@^0.3.6:
version "0.3.7"
resolved "https://registry.yarnpkg.com/sh-syntax/-/sh-syntax-0.3.7.tgz#8b86862c2de1488dd8fb9a9306e2124501617ae3"
@@ -3304,27 +3241,27 @@ slash@^4.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
smart-buffer@^4.1.0:
smart-buffer@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
socks-proxy-agent@5, socks-proxy-agent@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e"
integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==
socks-proxy-agent@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz#ffc5859a66dac89b0c4dab90253b96705f3e7120"
integrity sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ==
dependencies:
agent-base "^6.0.2"
debug "4"
socks "^2.3.3"
agent-base "^7.0.1"
debug "^4.3.4"
socks "^2.7.1"
socks@^2.3.3:
version "2.6.1"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e"
integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==
socks@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55"
integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==
dependencies:
ip "^1.1.5"
smart-buffer "^4.1.0"
ip "^2.0.0"
smart-buffer "^4.2.0"
source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
@@ -3357,11 +3294,6 @@ spdx-license-ids@^3.0.0:
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65"
integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==
split2@^4.0.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4"
integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==
split@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
@@ -3452,11 +3384,6 @@ string_decoder@^1.1.1:
dependencies:
safe-buffer "~5.2.0"
string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
@@ -3541,11 +3468,6 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
toidentifier@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
@@ -3653,10 +3575,10 @@ typed-array-length@^1.0.4:
for-each "^0.3.3"
is-typed-array "^1.1.9"
typescript@^4.6.2:
version "4.6.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==
typescript@^5.0.4:
version "5.0.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
unbox-primitive@^1.0.2:
version "1.0.2"
@@ -3773,7 +3695,7 @@ vfile@^4.0.0:
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
vm2@^3.9.11, vm2@^3.9.3:
vm2@^3.9.11, vm2@^3.9.17:
version "3.9.19"
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.19.tgz#be1e1d7a106122c6c492b4d51c2e8b93d3ed6a4a"
integrity sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==
@@ -3860,21 +3782,11 @@ xdg-basedir@^4.0.0:
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
xregexp@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"