Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
Coder
code-server
提交
ba728519
C
code-server
项目概览
镜像
/
Coder
/
code-server
2022-09-21 03:15:05同步失败
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
code-server
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
ba728519
编写于
8月 09, 2019
作者:
A
Asher
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update VS Code to 1.37.0
上级
b257c606
变更
21
展开全部
隐藏空白更改
内联
并排
Showing
21 changed file
with
645 addition
and
1590 deletion
+645
-1590
.travis.yml
.travis.yml
+3
-3
README.md
README.md
+7
-11
scripts/build-json.js
scripts/build-json.js
+58
-0
scripts/merge.js
scripts/merge.js
+0
-23
scripts/tasks.bash
scripts/tasks.bash
+4
-6
scripts/vscode.patch
scripts/vscode.patch
+287
-1376
src/api.ts
src/api.ts
+22
-23
src/channel.ts
src/channel.ts
+6
-8
src/cli.ts
src/cli.ts
+14
-27
src/client.ts
src/client.ts
+23
-2
src/connection.ts
src/connection.ts
+3
-5
src/insights.ts
src/insights.ts
+1
-2
src/ipc.ts
src/ipc.ts
+0
-1
src/marketplace.ts
src/marketplace.ts
+14
-6
src/nls.ts
src/nls.ts
+1
-2
src/protocol.ts
src/protocol.ts
+1
-2
src/server.ts
src/server.ts
+55
-36
src/telemetry.ts
src/telemetry.ts
+49
-0
src/update.ts
src/update.ts
+15
-10
src/upload.ts
src/upload.ts
+70
-43
src/util.ts
src/util.ts
+12
-4
未找到文件。
.travis.yml
浏览文件 @
ba728519
...
...
@@ -8,14 +8,14 @@ matrix:
-
os
:
linux
dist
:
trusty
env
:
-
VSCODE_VERSION="1.3
6.1
" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="linux"
-
VSCODE_VERSION="1.3
7.0
" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="linux"
-
os
:
linux
dist
:
trusty
env
:
-
VSCODE_VERSION="1.3
6.1
" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="alpine"
-
VSCODE_VERSION="1.3
7.0
" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER" TARGET="alpine"
-
os
:
osx
env
:
-
VSCODE_VERSION="1.3
6.1
" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER"
-
VSCODE_VERSION="1.3
7.0
" MAJOR_VERSION="2" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER"
before_install
:
-
if [[ "$TRAVIS_BRANCH" == "master" ]]; then export MINIFY="true"; fi
script
:
...
...
README.md
浏览文件 @
ba728519
...
...
@@ -81,7 +81,7 @@ data collected to improve code-server.
```
shell
git clone https://github.com/microsoft/vscode
cd
vscode
git checkout 1.3
6.1
git checkout 1.3
7.0
git clone https://github.com/cdr/code-server src/vs/server
cd
src/vs/server
yarn patch:apply
...
...
@@ -109,23 +109,19 @@ directory.
Our changes include:
-
Add a
`code-server`
schema.
-
Make the extension sidebar work in the browser. Mostly involves removing
Node-specific code for the
`extensions`
channel client and adding a
`gallery`
channel.
-
Allow multiple extension directories (both user and built-in).
-
Rewrite assets used in the CSS (like icons) or as images to use the base URL.
-
Change the loader to use the base URL.
-
Change the web socket to use the base URL and TLS if necessary.
-
Set the favicon using a relative path.
-
Modify the file service to support writing from an asynchronous stream (for
uploading files).
-
Rewrite assets requested by the browser to use the base URL.
-
Modify the loader to use the base URL.
-
Modify the web socket to use the base URL and TLS if necessary.
-
Send client-side telemetry through the server.
-
Add a file prefix to ignore for temporary files created during upload.
-
Insert our upload service for use in editor windows and explorer.
-
Modify the log level to get its initial setting from the server.
-
Get telemetry working by adding a channel for it.
-
Change a regular expression used for mnemonics so it works on Firefox.
-
Make it possible for us to load code on the client.
-
Modify the build process to include our code.
-
Fix a CSP issue within a webview.
-
Fix an issue displaying extension contributions.
## License
[
MIT
](
LICENSE
)
...
...
scripts/build-json.js
0 → 100644
浏览文件 @
ba728519
// This builds the package and product JSON files for the final build.
const
crypto
=
require
(
"
crypto
"
);
const
fs
=
require
(
"
fs
"
);
const
path
=
require
(
"
path
"
);
const
rootPath
=
path
.
resolve
(
__dirname
,
"
..
"
);
const
sourcePath
=
process
.
argv
[
2
];
const
buildPath
=
process
.
argv
[
3
];
const
vscodeVersion
=
process
.
argv
[
4
];
const
codeServerVersion
=
process
.
argv
[
5
];
const
util
=
require
(
path
.
join
(
sourcePath
,
"
build/lib/util
"
));
function
computeChecksum
(
filename
)
{
return
crypto
.
createHash
(
"
md5
"
).
update
(
fs
.
readFileSync
(
filename
))
.
digest
(
"
base64
"
).
replace
(
/=+$/
,
""
);
}
const
computeChecksums
=
(
filenames
)
=>
{
const
result
=
{};
filenames
.
forEach
(
function
(
filename
)
{
result
[
filename
]
=
computeChecksum
(
path
.
join
(
buildPath
,
"
out
"
,
filename
));
});
return
result
;
};
const
mergeAndWrite
=
(
name
,
json
=
{})
=>
{
const
aJson
=
JSON
.
parse
(
fs
.
readFileSync
(
path
.
join
(
sourcePath
,
`
${
name
}
.json`
)));
const
bJson
=
JSON
.
parse
(
fs
.
readFileSync
(
path
.
join
(
rootPath
,
"
scripts
"
,
`
${
name
}
.json`
)));
delete
aJson
.
scripts
;
delete
aJson
.
dependencies
;
delete
aJson
.
devDependencies
;
delete
aJson
.
optionalDependencies
;
fs
.
writeFileSync
(
path
.
join
(
buildPath
,
`
${
name
}
.json`
),
JSON
.
stringify
({
...
aJson
,
...
bJson
,
...
json
,
},
null
,
2
));
};
const
writeProduct
=
()
=>
{
const
checksums
=
computeChecksums
([
"
vs/workbench/workbench.web.api.js
"
,
"
vs/workbench/workbench.web.api.css
"
,
"
vs/code/browser/workbench/workbench.html
"
,
"
vs/code/browser/workbench/workbench.js
"
,
"
vs/server/src/cli.js
"
,
"
vs/server/src/uriTransformer.js
"
,
"
vs/server/src/login/index.html
"
]);
const
date
=
new
Date
().
toISOString
();
const
commit
=
util
.
getVersion
(
rootPath
);
mergeAndWrite
(
"
product
"
,
{
commit
,
date
,
checksums
});
mergeAndWrite
(
"
package
"
,
{
codeServerVersion
:
`
${
codeServerVersion
}
-vsc
${
vscodeVersion
}
`
});
};
writeProduct
();
scripts/merge.js
已删除
100644 → 0
浏览文件 @
b257c606
// This is used to merge JSON files (package.json and product.json) and delete a
// few entries we don't want. It's extremely simple, expects very specific
// input, and doesn't have any error handling.
const
fs
=
require
(
"
fs
"
);
const
a
=
process
.
argv
[
2
];
const
b
=
process
.
argv
[
3
];
const
out
=
process
.
argv
[
4
];
const
json
=
JSON
.
parse
(
process
.
argv
[
5
]
||
"
{}
"
);
const
aJson
=
JSON
.
parse
(
fs
.
readFileSync
(
a
));
const
bJson
=
JSON
.
parse
(
fs
.
readFileSync
(
b
));
delete
aJson
.
scripts
;
delete
aJson
.
dependencies
;
delete
aJson
.
devDependencies
;
delete
aJson
.
optionalDependencies
;
fs
.
writeFileSync
(
out
,
JSON
.
stringify
({
...
aJson
,
...
bJson
,
...
json
,
},
null
,
2
));
scripts/tasks.bash
浏览文件 @
ba728519
...
...
@@ -56,9 +56,9 @@ function prepend-loader() {
# Copy code-server into VS Code then build it.
function
build-code-server
()
{
copy-server
yarn gulp compile-build
--max-old-space-size
=
32384
local
min
=
""
export
BUILD_SOURCEVERSION
BUILD_SOURCEVERSION
=
$(
node
-p
"require('
${
sourcePath
}
/build/lib/git.js').getVersion('
${
rootPath
}
')"
)
if
[[
-n
"
${
minify
}
"
]]
;
then
min
=
"-min"
yarn gulp minify-vscode
--max-old-space-size
=
32384
...
...
@@ -74,11 +74,9 @@ function build-code-server() {
cd
"
${
buildPath
}
"
&&
yarn
--production
--force
--build-from-source
rm
"
${
buildPath
}
/"
{
package.json,yarn.lock,.yarnrc
}
local
packageJson
=
"{
\"
codeServerVersion
\"
:
\"
${
codeServerVersion
}
-vsc
${
vscodeVersion
}
\"
}"
cp
-r
"
${
sourcePath
}
/.build/extensions"
"
${
buildPath
}
"
node
"
${
rootPath
}
/scripts/merge.js"
"
${
sourcePath
}
/package.json"
"
${
rootPath
}
/scripts/package.json"
"
${
buildPath
}
/package.json"
"
${
packageJson
}
"
node
"
${
rootPath
}
/scripts/merge.js"
"
${
sourcePath
}
/.build/product.json"
"
${
rootPath
}
/scripts/product.json"
"
${
buildPath
}
/product.json"
cp
-r
"
${
sourcePath
}
/out-vscode
${
min
}
"
"
${
buildPath
}
/out"
node
"
${
rootPath
}
/scripts/build-json.js"
"
${
sourcePath
}
"
"
${
buildPath
}
"
"
${
vscodeVersion
}
"
"
${
codeServerVersion
}
"
# Only keep production dependencies for the server.
cp
"
${
rootPath
}
/"
{
package.json,yarn.lock
}
"
${
buildPath
}
/out/vs/server"
...
...
@@ -143,7 +141,7 @@ function build-task() {
log
"Pre-built VS Code
${
vscodeVersion
}
has no built extensions"
"error"
exit
1
fi
yarn gulp
extensions-build-package
--max-old-space-size
=
32384
yarn gulp
compile-extensions-build
--max-old-space-size
=
32384
fi
build-code-server
}
...
...
scripts/vscode.patch
浏览文件 @
ba728519
此差异已折叠。
点击以展开。
src/api.ts
浏览文件 @
ba728519
import
*
as
vscode
from
"
vscode
"
;
import
{
createCSSRule
}
from
"
vs/base/browser/dom
"
;
import
{
Emitter
,
Event
}
from
"
vs/base/common/event
"
;
import
{
IDisposable
}
from
"
vs/base/common/lifecycle
"
;
import
{
URI
}
from
"
vs/base/common/uri
"
;
import
{
generateUuid
}
from
"
vs/base/common/uuid
"
;
import
{
localize
}
from
"
vs/nls
"
;
import
{
SyncActionDescriptor
}
from
"
vs/platform/actions/common/actions
"
;
import
{
Registry
}
from
"
vs/platform/registry/common/platform
"
;
import
{
IWorkbenchActionRegistry
,
Extensions
as
ActionExtensions
}
from
"
vs/workbench/common/actions
"
;
import
{
CommandsRegistry
,
ICommandService
}
from
"
vs/platform/commands/common/commands
"
;
import
{
IStat
,
IWatchOptions
,
FileOverwriteOptions
,
FileDeleteOptions
,
FileOpenOptions
,
IFileChange
,
FileWriteOptions
,
FileSystemProviderCapabilities
,
IFileService
,
FileType
,
IFileSystemProvider
}
from
"
vs/platform/files/common/files
"
;
import
{
IStorageService
}
from
"
vs/platform/storage/common/storage
"
;
import
{
IConfigurationService
}
from
"
vs/platform/configuration/common/configuration
"
;
import
{
IContextMenuService
}
from
"
vs/platform/contextview/browser/contextView
"
;
import
{
FileDeleteOptions
,
FileOpenOptions
,
FileOverwriteOptions
,
FileSystemProviderCapabilities
,
FileType
,
FileWriteOptions
,
IFileChange
,
IFileService
,
IFileSystemProvider
,
IStat
,
IWatchOptions
}
from
"
vs/platform/files/common/files
"
;
import
{
IInstantiationService
,
ServiceIdentifier
}
from
"
vs/platform/instantiation/common/instantiation
"
;
import
{
ServiceCollection
}
from
"
vs/platform/instantiation/common/serviceCollection
"
;
import
{
INotificationService
}
from
"
vs/platform/notification/common/notification
"
;
import
{
Emitter
,
Event
}
from
"
vs/base/common/event
"
;
import
*
as
extHostTypes
from
"
vs/workbench/api/common/extHostTypes
"
;
import
{
ServiceIdentifier
,
IInstantiationService
}
from
"
vs/platform/instantiation/common/instantiation
"
;
import
{
URI
}
from
"
vs/base/common/uri
"
;
import
{
ITreeItem
,
ITreeViewDataProvider
,
IViewsRegistry
,
ITreeViewDescriptor
,
Extensions
as
ViewsExtensions
,
IViewContainersRegistry
,
TreeItemCollapsibleState
}
from
"
vs/workbench/common/views
"
;
import
{
CustomTreeViewPanel
,
CustomTreeView
}
from
"
vs/workbench/browser/parts/views/customView
"
;
import
{
ViewletRegistry
,
Extensions
as
ViewletExtensions
,
ViewletDescriptor
,
ShowViewletAction
}
from
"
vs/workbench/browser/viewlet
"
;
import
{
IExtensionService
}
from
"
vs/workbench/services/extensions/common/extensions
"
;
import
{
ViewContainerViewlet
}
from
"
vs/workbench/browser/parts/views/viewsViewlet
"
;
import
{
IConfigurationService
}
from
"
vs/platform/configuration/common/configuration
"
;
import
{
IWorkbenchLayoutService
}
from
"
vs/workbench/services/layout/browser/layoutService
"
;
import
{
Registry
}
from
"
vs/platform/registry/common/platform
"
;
import
{
IStorageService
}
from
"
vs/platform/storage/common/storage
"
;
import
{
ITelemetryService
}
from
"
vs/platform/telemetry/common/telemetry
"
;
import
{
IThemeService
}
from
"
vs/platform/theme/common/themeService
"
;
import
{
IWorkspaceContextService
}
from
"
vs/platform/workspace/common/workspace
"
;
import
*
as
extHostTypes
from
"
vs/workbench/api/common/extHostTypes
"
;
import
{
CustomTreeView
,
CustomTreeViewPanel
}
from
"
vs/workbench/browser/parts/views/customView
"
;
import
{
ViewContainerViewlet
}
from
"
vs/workbench/browser/parts/views/viewsViewlet
"
;
import
{
Extensions
as
ViewletExtensions
,
ShowViewletAction
,
ViewletDescriptor
,
ViewletRegistry
}
from
"
vs/workbench/browser/viewlet
"
;
import
{
Extensions
as
ActionExtensions
,
IWorkbenchActionRegistry
}
from
"
vs/workbench/common/actions
"
;
import
{
Extensions
as
ViewsExtensions
,
ITreeItem
,
ITreeViewDataProvider
,
ITreeViewDescriptor
,
IViewContainersRegistry
,
IViewsRegistry
,
TreeItemCollapsibleState
}
from
"
vs/workbench/common/views
"
;
import
{
IEditorGroupsService
}
from
"
vs/workbench/services/editor/common/editorGroupsService
"
;
import
{
IEditorService
}
from
"
vs/workbench/services/editor/common/editorService
"
;
import
{
I
ThemeService
}
from
"
vs/platform/theme/common/themeService
"
;
import
{
I
ContextMenuService
}
from
"
vs/platform/contextview/browser/contextView
"
;
import
{
I
ExtensionService
}
from
"
vs/workbench/services/extensions/common/extensions
"
;
import
{
I
WorkbenchLayoutService
}
from
"
vs/workbench/services/layout/browser/layoutService
"
;
import
{
IViewletService
}
from
"
vs/workbench/services/viewlet/browser/viewlet
"
;
import
{
IEditorGroupsService
}
from
"
vs/workbench/services/editor/common/editorGroupsService
"
;
import
{
createCSSRule
}
from
"
vs/base/browser/dom
"
;
import
{
IDisposable
}
from
"
vs/base/common/lifecycle
"
;
import
{
generateUuid
}
from
"
vs/base/common/uuid
"
;
import
*
as
vscode
from
"
vscode
"
;
/**
* Client-side implementation of VS Code's API.
...
...
src/channel.ts
浏览文件 @
ba728519
import
*
as
path
from
"
path
"
;
import
{
VSBuffer
}
from
"
vs/base/common/buffer
"
;
import
{
Emitter
,
Event
}
from
"
vs/base/common/event
"
;
import
{
IDisposable
}
from
"
vs/base/common/lifecycle
"
;
...
...
@@ -9,18 +8,17 @@ import { transformOutgoingURIs } from "vs/base/common/uriIpc";
import
{
IServerChannel
}
from
"
vs/base/parts/ipc/common/ipc
"
;
import
{
IDiagnosticInfo
}
from
"
vs/platform/diagnostics/common/diagnosticsService
"
;
import
{
IEnvironmentService
}
from
"
vs/platform/environment/common/environment
"
;
import
{
IExtensionDescription
,
ExtensionIdentifier
}
from
"
vs/platform/extensions/common/extensions
"
;
import
{
FileDeleteOptions
,
FileOverwriteOptions
,
FileType
,
IStat
,
IWatchOptions
,
FileOpenOptions
}
from
"
vs/platform/files/common/files
"
;
import
{
ExtensionIdentifier
,
IExtensionDescription
}
from
"
vs/platform/extensions/common/extensions
"
;
import
{
FileDeleteOptions
,
FileOpenOptions
,
FileOverwriteOptions
,
FileType
,
IStat
,
IWatchOptions
}
from
"
vs/platform/files/common/files
"
;
import
{
DiskFileSystemProvider
}
from
"
vs/platform/files/node/diskFileSystemProvider
"
;
import
{
ILogService
}
from
"
vs/platform/log/common/log
"
;
import
pkg
from
"
vs/platform/product/node/package
"
;
import
product
from
"
vs/platform/product/node/product
"
;
import
{
IRemoteAgentEnvironment
}
from
"
vs/platform/remote/common/remoteAgentEnvironment
"
;
import
{
ITelemetryService
}
from
"
vs/platform/telemetry/common/telemetry
"
;
import
{
ExtensionScanner
,
ExtensionScannerInput
}
from
"
vs/workbench/services/extensions/node/extensionPoints
"
;
import
{
DiskFileSystemProvider
}
from
"
vs/workbench/services/files/node/diskFileSystemProvider
"
;
import
{
getTranslations
}
from
"
vs/server/src/nls
"
;
import
{
getUriTransformer
}
from
"
vs/server/src/util
"
;
import
{
ExtensionScanner
,
ExtensionScannerInput
}
from
"
vs/workbench/services/extensions/node/extensionPoints
"
;
/**
* Extend the file provider to allow unwatching.
...
...
@@ -205,7 +203,7 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
appSettingsHome
:
this
.
environment
.
appSettingsHome
,
settingsPath
:
this
.
environment
.
machineSettingsHome
,
logsPath
:
URI
.
file
(
this
.
environment
.
logsPath
),
extensionsPath
:
URI
.
file
(
this
.
environment
.
extensionsPath
),
extensionsPath
:
URI
.
file
(
this
.
environment
.
extensionsPath
!
),
extensionHostLogsPath
:
URI
.
file
(
path
.
join
(
this
.
environment
.
logsPath
,
"
extension-host
"
)),
globalStorageHome
:
URI
.
file
(
this
.
environment
.
globalStorageHome
),
userHome
:
URI
.
file
(
this
.
environment
.
userHome
),
...
...
@@ -237,7 +235,7 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
};
const
scanInstalled
=
async
():
Promise
<
IExtensionDescription
[][]
>
=>
{
return
scanMultiple
(
false
,
true
,
[
this
.
environment
.
extensionsPath
,
...
this
.
environment
.
extraExtensionPaths
]);
return
scanMultiple
(
false
,
true
,
[
this
.
environment
.
extensionsPath
!
,
...
this
.
environment
.
extraExtensionPaths
]);
};
return
Promise
.
all
([
scanBuiltin
(),
scanInstalled
()]).
then
((
allExtensions
)
=>
{
...
...
src/cli.ts
浏览文件 @
ba728519
import
*
as
cp
from
"
child_process
"
;
import
*
as
os
from
"
os
"
;
import
{
main
as
vsCli
}
from
"
vs/code/node/cliProcessMain
"
;
import
{
validatePaths
}
from
"
vs/code/node/paths
"
;
import
{
parseMainProcessArgv
}
from
"
vs/platform/environment/node/argvHelper
"
;
import
{
buildHelpMessage
,
buildVersionMessage
,
options
}
from
"
vs/platform/environment/node/argv
"
;
import
{
ParsedArgs
}
from
"
vs/platform/environment/common/environment
"
;
import
{
buildHelpMessage
,
buildVersionMessage
,
Option
as
VsOption
,
options
as
vsOptions
}
from
"
vs/platform/environment/node/argv
"
;
import
{
parseMainProcessArgv
}
from
"
vs/platform/environment/node/argvHelper
"
;
import
pkg
from
"
vs/platform/product/node/package
"
;
import
product
from
"
vs/platform/product/node/product
"
;
import
{
ipcMain
}
from
"
vs/server/src/ipc
"
;
product
.
extensionsGallery
=
{
serviceUrl
:
process
.
env
.
SERVICE_URL
||
"
https://v1.extapi.coder.com
"
,
itemUrl
:
process
.
env
.
ITEM_URL
||
""
,
controlUrl
:
""
,
recommendationsUrl
:
""
,
...(
product
.
extensionsGallery
||
{}),
};
import
{
enableCustomMarketplace
}
from
"
vs/server/src/marketplace
"
;
import
{
MainServer
}
from
"
vs/server/src/server
"
;
import
{
enableExtensionTars
}
from
"
vs/server/src/tar
"
;
import
{
AuthType
,
buildAllowedMessage
,
generateCertificate
,
generatePassword
,
localRequire
,
open
,
unpackExecutables
}
from
"
vs/server/src/util
"
;
import
{
AuthType
,
buildAllowedMessage
,
enumToArray
,
generateCertificate
,
generatePassword
,
localRequire
,
open
,
unpackExecutables
}
from
"
vs/server/src/util
"
;
const
{
logger
}
=
localRequire
<
typeof
import
(
"
@coder/logger/out/index
"
)
>
(
"
@coder/logger/out/index
"
);
...
...
@@ -30,15 +19,19 @@ interface Args extends ParsedArgs {
"
base-path
"
?:
string
;
cert
?:
string
;
"
cert-key
"
?:
string
;
"
extra-builtin-extensions-dir
"
?:
string
;
"
extra-extensions-dir
"
?:
string
;
host
?:
string
;
open
?:
string
;
port
?:
string
;
socket
?:
string
;
}
// @ts-ignore: Force `keyof Args` to work.
interface
Option
extends
VsOption
{
id
:
keyof
Args
;
}
const
getArgs
=
():
Args
=>
{
const
options
=
vsOptions
as
Option
[];
// The last item is _ which is like -- so our options need to come before it.
const
last
=
options
.
pop
()
!
;
...
...
@@ -78,13 +71,7 @@ const getArgs = (): Args => {
options
.
push
(
last
);
const
args
=
validatePaths
(
parseMainProcessArgv
(
process
.
argv
))
as
Args
;
[
"
extra-extensions-dir
"
,
"
extra-builtin-extensions-dir
"
].
forEach
((
key
)
=>
{
if
(
typeof
args
[
key
]
===
"
string
"
)
{
args
[
key
]
=
[
args
[
key
]];
}
});
return
args
;
return
validatePaths
(
parseMainProcessArgv
(
process
.
argv
));
};
const
startVscode
=
async
():
Promise
<
void
|
void
[]
>
=>
{
...
...
@@ -100,7 +87,7 @@ const startVscode = async (): Promise<void | void[]> => {
password
:
process
.
env
.
PASSWORD
,
};
if
(
options
.
auth
&&
Object
.
keys
(
AuthType
).
filter
((
k
)
=>
AuthType
[
k
]
===
options
.
auth
).
length
===
0
)
{
if
(
options
.
auth
&&
enumToArray
(
AuthType
).
filter
((
t
)
=>
t
===
options
.
auth
).
length
===
0
)
{
throw
new
Error
(
`'
${
options
.
auth
}
' is not a valid authentication type.`
);
}
else
if
(
options
.
auth
&&
!
options
.
password
)
{
options
.
password
=
await
generatePassword
();
...
...
@@ -116,7 +103,7 @@ const startVscode = async (): Promise<void | void[]> => {
options
.
certKey
=
certKey
;
}
enable
ExtensionTars
();
enable
CustomMarketplace
();
const
server
=
new
MainServer
({
...
options
,
...
...
@@ -180,7 +167,7 @@ const startCli = (): boolean | Promise<void> => {
};
if
(
shouldSpawnCliProcess
())
{
enable
ExtensionTars
();
enable
CustomMarketplace
();
return
vsCli
(
args
);
}
...
...
src/client.ts
浏览文件 @
ba728519
import
{
registerSingleton
}
from
"
vs/platform/instantiation/common/extensions
"
;
import
{
ServiceCollection
}
from
"
vs/platform/instantiation/common/serviceCollection
"
;
import
{
ITelemetryService
}
from
"
vs/platform/telemetry/common/telemetry
"
;
import
{
ILocalizationsService
}
from
"
vs/platform/localizations/common/localizations
"
;
import
{
LocalizationsService
}
from
"
vs/platform/localizations/electron-browser/localizationsService
"
;
import
{
IUpdateService
}
from
"
vs/platform/update/common/update
"
;
import
{
UpdateService
}
from
"
vs/platform/update/electron-browser/updateService
"
;
import
{
TelemetryChannelClient
}
from
"
vs/server/src/telemetry
"
;
import
{
IRemoteAgentService
}
from
"
vs/workbench/services/remote/common/remoteAgentService
"
;
import
{
coderApi
,
vscodeApi
}
from
"
vs/server/src/api
"
;
class
TelemetryService
extends
TelemetryChannelClient
{
public
constructor
(
@
IRemoteAgentService
remoteAgentService
:
IRemoteAgentService
,
)
{
super
(
remoteAgentService
.
getConnection
()
!
.
getChannel
(
"
telemetry
"
));
}
}
registerSingleton
(
ILocalizationsService
,
LocalizationsService
);
registerSingleton
(
IUpdateService
,
UpdateService
);
registerSingleton
(
ITelemetryService
,
TelemetryService
);
import
"
vs/workbench/contrib/update/electron-browser/update.contribution
"
;
import
"
vs/css!./media/firefox
"
;
import
{
coderApi
,
vscodeApi
}
from
"
vs/server/src/api
"
;
/**
* This is called by vs/workbench/browser/web.main.ts after the workbench has
...
...
@@ -13,7 +34,7 @@ export const initialize = async (services: ServiceCollection): Promise<void> =>
target
.
ide
=
coderApi
(
services
);
target
.
vscode
=
vscodeApi
(
services
);
const
event
=
new
CustomEvent
(
'
ide-ready
'
);
const
event
=
new
CustomEvent
(
"
ide-ready
"
);
(
event
as
any
).
ide
=
target
.
ide
;
(
event
as
any
).
vscode
=
target
.
vscode
;
window
.
dispatchEvent
(
event
);
...
...
src/connection.ts
浏览文件 @
ba728519
import
*
as
cp
from
"
child_process
"
;
import
{
getPathFromAmdModule
}
from
"
vs/base/common/amd
"
;
import
{
VSBuffer
}
from
"
vs/base/common/buffer
"
;
import
{
Emitter
}
from
"
vs/base/common/event
"
;
...
...
@@ -7,11 +6,10 @@ import { ISocket } from "vs/base/parts/ipc/common/ipc.net";
import
{
NodeSocket
}
from
"
vs/base/parts/ipc/node/ipc.net
"
;
import
{
IEnvironmentService
}
from
"
vs/platform/environment/common/environment
"
;
import
{
ILogService
}
from
"
vs/platform/log/common/log
"
;
import
{
IExtHostReadyMessage
}
from
"
vs/workbench/services/extensions/common/extensionHostProtocol
"
;
import
{
getNlsConfiguration
}
from
"
vs/server/src/nls
"
;
import
{
Protocol
}
from
"
vs/server/src/protocol
"
;
import
{
uriTransformerPath
}
from
"
vs/server/src/util
"
;
import
{
IExtHostReadyMessage
}
from
"
vs/workbench/services/extensions/common/extensionHostProtocol
"
;
export
abstract
class
Connection
{
protected
readonly
_onClose
=
new
Emitter
<
void
>
();
...
...
@@ -126,8 +124,8 @@ export class ExtensionHostConnection extends Connection {
proc
.
stderr
.
setEncoding
(
"
utf8
"
).
on
(
"
data
"
,
(
d
)
=>
this
.
log
.
error
(
"
Extension host stderr
"
,
d
));
proc
.
on
(
"
message
"
,
(
event
)
=>
{
if
(
event
&&
event
.
type
===
"
__$console
"
)
{
const
severity
=
this
.
log
[
event
.
severity
]
?
event
.
severity
:
"
info
"
;
this
.
log
[
severity
](
"
Extension host
"
,
event
.
arguments
);
const
severity
=
(
<
any
>
this
.
log
)
[
event
.
severity
]
?
event
.
severity
:
"
info
"
;
(
<
any
>
this
.
log
)
[
severity
](
"
Extension host
"
,
event
.
arguments
);
}
});
...
...
src/insights.ts
浏览文件 @
ba728519
import
*
as
appInsights
from
"
applicationinsights
"
;
import
*
as
https
from
"
https
"
;
import
*
as
os
from
"
os
"
;
import
*
as
appInsights
from
"
applicationinsights
"
;
export
class
TelemetryClient
implements
appInsights
.
TelemetryClient
{
public
config
:
any
=
{};
...
...
src/ipc.ts
浏览文件 @
ba728519
import
*
as
cp
from
"
child_process
"
;
import
{
Emitter
}
from
"
vs/base/common/event
"
;
enum
ControlMessage
{
...
...
src/
tar
.ts
→
src/
marketplace
.ts
浏览文件 @
ba728519
...
...
@@ -2,11 +2,11 @@ import * as fs from "fs";
import
*
as
path
from
"
path
"
;
import
*
as
tarStream
from
"
tar-stream
"
;
import
*
as
util
from
"
util
"
;
import
*
as
nls
from
"
vs/nls
"
;
import
*
as
vszip
from
"
vs/base/node/zip
"
;
import
{
CancellationToken
}
from
"
vs/base/common/cancellation
"
;
import
{
mkdirp
}
from
"
vs/base/node/pfs
"
;
import
*
as
vszip
from
"
vs/base/node/zip
"
;
import
*
as
nls
from
"
vs/nls
"
;
import
product
from
"
vs/platform/product/node/product
"
;
// We will be overriding these, so keep a reference to the original.
const
vszipExtract
=
vszip
.
extract
;
...
...
@@ -154,10 +154,18 @@ const extractTar = async (tarPath: string, targetPath: string, options: IExtract
};
/**
* Override original functionality so we can use
extensions that are in a tar in
*
addition to
zips.
* Override original functionality so we can use
a custom marketplace with
*
either tars or
zips.
*/
export
const
enableExtensionTars
=
():
void
=>
{
export
const
enableCustomMarketplace
=
():
void
=>
{
(
<
any
>
product
).
extensionsGallery
=
{
// Use `any` to override readonly.
serviceUrl
:
process
.
env
.
SERVICE_URL
||
"
https://v1.extapi.coder.com
"
,
itemUrl
:
process
.
env
.
ITEM_URL
||
""
,
controlUrl
:
""
,
recommendationsUrl
:
""
,
...(
product
.
extensionsGallery
||
{}),
};
const
target
=
vszip
as
typeof
vszip
;
target
.
zip
=
tar
;
target
.
extract
=
extract
;
...
...
src/nls.ts
浏览文件 @
ba728519
import
*
as
path
from
"
path
"
;
import
*
as
fs
from
"
fs
"
;
import
*
as
path
from
"
path
"
;
import
*
as
util
from
"
util
"
;
import
{
getPathFromAmdModule
}
from
"
vs/base/common/amd
"
;
import
*
as
lp
from
"
vs/base/node/languagePacks
"
;
import
product
from
"
vs/platform/product/node/product
"
;
...
...
src/protocol.ts
浏览文件 @
ba728519
import
*
as
net
from
"
net
"
;
import
{
VSBuffer
}
from
"
vs/base/common/buffer
"
;
import
{
NodeSocket
,
WebSocketNodeSocket
}
from
"
vs/base/parts/ipc/node/ipc.net
"
;
import
{
PersistentProtocol
}
from
"
vs/base/parts/ipc/common/ipc.net
"
;
import
{
NodeSocket
,
WebSocketNodeSocket
}
from
"
vs/base/parts/ipc/node/ipc.net
"
;
import
{
AuthRequest
,
ConnectionTypeRequest
,
HandshakeMessage
}
from
"
vs/platform/remote/common/remoteAgentConnection
"
;
export
interface
SocketOptions
{
...
...
src/server.ts
浏览文件 @
ba728519
...
...
@@ -4,31 +4,34 @@ import * as http from "http";
import
*
as
https
from
"
https
"
;
import
*
as
net
from
"
net
"
;
import
*
as
path
from
"
path
"
;
import
*
as
querystring
from
"
querystring
"
;
import
*
as
tls
from
"
tls
"
;
import
*
as
util
from
"
util
"
;
import
*
as
url
from
"
url
"
;
import
*
as
querystring
from
"
querystring
"
;
import
*
as
util
from
"
util
"
;
import
{
Emitter
}
from
"
vs/base/common/event
"
;
import
{
sanitizeFilePath
}
from
"
vs/base/common/extpath
"
;
import
{
UriComponents
,
URI
}
from
"
vs/base/common/uri
"
;
import
{
Schemas
}
from
"
vs/base/common/network
"
;
import
{
URI
,
UriComponents
}
from
"
vs/base/common/uri
"
;
import
{
generateUuid
}
from
"
vs/base/common/uuid
"
;
import
{
getMachineId
}
from
'
vs/base/node/id
'
;
import
{
NLSConfiguration
}
from
"
vs/base/node/languagePacks
"
;
import
{
mkdirp
,
rimraf
}
from
"
vs/base/node/pfs
"
;
import
{
IPCServer
,
ClientConnectionEvent
,
StaticRouter
}
from
"
vs/base/parts/ipc/common/ipc
"
;
import
{
ClientConnectionEvent
,
IPCServer
,
StaticRouter
}
from
"
vs/base/parts/ipc/common/ipc
"
;
import
{
LogsDataCleaner
}
from
"
vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner
"
;
import
{
IConfigurationService
}
from
"
vs/platform/configuration/common/configuration
"
;
import
{
ConfigurationService
}
from
"
vs/platform/configuration/node/configurationService
"
;
import
{
ExtensionHostDebugBroadcastChannel
}
from
"
vs/platform/debug/common/extensionHostDebugIpc
"
;
import
{
IDialogService
}
from
"
vs/platform/dialogs/common/dialogs
"
;
import
{
DialogChannelClient
}
from
"
vs/platform/dialogs/node/dialogIpc
"
;
import
{
IEnvironmentService
,
ParsedArgs
}
from
"
vs/platform/environment/common/environment
"
;
import
{
EnvironmentService
}
from
"
vs/platform/environment/node/environmentService
"
;
import
{
IExtensionManagementService
,
IExtensionGalleryService
}
from
"
vs/platform/extensionManagement/common/extensionManagement
"
;
import
{
ExtensionGalleryChannel
}
from
"
vs/platform/extensionManagement/node/extensionGalleryIpc
"
;
import
{
ExtensionGalleryService
}
from
"
vs/platform/extensionManagement/node/extensionGalleryService
"
;
import
{
ExtensionManagementChannel
}
from
"
vs/platform/extensionManagement/node/extensionManagementIpc
"
;
import
{
ExtensionGalleryService
}
from
"
vs/platform/extensionManagement/common/extensionGalleryService
"
;
import
{
IExtensionGalleryService
,
IExtensionManagementService
}
from
"
vs/platform/extensionManagement/common/extensionManagement
"
;
import
{
ExtensionManagementChannel
}
from
"
vs/platform/extensionManagement/common/extensionManagementIpc
"
;
import
{
ExtensionManagementService
}
from
"
vs/platform/extensionManagement/node/extensionManagementService
"
;
import
{
IFileService
}
from
"
vs/platform/files/common/files
"
;
import
{
FileService
}
from
"
vs/platform/files/common/fileService
"
;
import
{
DiskFileSystemProvider
}
from
"
vs/platform/files/node/diskFileSystemProvider
"
;
import
{
SyncDescriptor
}
from
"
vs/platform/instantiation/common/descriptors
"
;
import
{
InstantiationService
}
from
"
vs/platform/instantiation/common/instantiationService
"
;
import
{
ServiceCollection
}
from
"
vs/platform/instantiation/common/serviceCollection
"
;
...
...
@@ -38,31 +41,32 @@ import { LocalizationsChannel } from "vs/platform/localizations/node/localizatio
import
{
getLogLevel
,
ILogService
}
from
"
vs/platform/log/common/log
"
;
import
{
LogLevelSetterChannel
}
from
"
vs/platform/log/common/logIpc
"
;
import
{
SpdLogService
}
from
"
vs/platform/log/node/spdlogService
"
;
import
{
IProductConfiguration
}
from
"
vs/platform/product/common/product
"
;
import
{
IProductConfiguration
,
IProductService
}
from
"
vs/platform/product/common/product
"
;
import
pkg
from
"
vs/platform/product/node/package
"
;
import
product
from
"
vs/platform/product/node/product
"
;
import
{
ProductService
}
from
"
vs/platform/product/node/productService
"
;
import
{
ConnectionType
,
ConnectionTypeRequest
}
from
"
vs/platform/remote/common/remoteAgentConnection
"
;
import
{
REMOTE_FILE_SYSTEM_CHANNEL_NAME
}
from
"
vs/platform/remote/common/remoteAgentFileSystemChannel
"
;
import
{
IRequestService
}
from
"
vs/platform/request/node/request
"
;
import
{
IRequestService
}
from
"
vs/platform/request/common/request
"
;
import
{
RequestChannel
}
from
"
vs/platform/request/common/requestIpc
"
;
import
{
RequestService
}
from
"
vs/platform/request/node/requestService
"
;
import
ErrorTelemetry
from
"
vs/platform/telemetry/browser/errorTelemetry
"
;
import
{
ITelemetryService
}
from
"
vs/platform/telemetry/common/telemetry
"
;
import
{
NullTelemetryService
,
LogAppender
,
combinedAppender
}
from
"
vs/platform/telemetry/common/telemetryUtils
"
;
import
{
TelemetryService
,
ITelemetryServiceConfig
}
from
"
vs/platform/telemetry/common/telemetryService
"
;
import
{
ITelemetryServiceConfig
,
TelemetryService
}
from
"
vs/platform/telemetry/common/telemetryService
"
;
import
{
combinedAppender
,
LogAppender
,
NullTelemetryService
}
from
"
vs/platform/telemetry/common/telemetryUtils
"
;
import
{
AppInsightsAppender
}
from
"
vs/platform/telemetry/node/appInsightsAppender
"
;
import
{
resolveCommonProperties
}
from
"
vs/platform/telemetry/node/commonProperties
"
;
import
{
RemoteExtensionLogFileName
}
from
"
vs/workbench/services/remote/common/remoteAgentService
"
;
import
{
TelemetryChannel
}
from
"
vs/platform/telemetry/node/telemetryIpc
"
;
import
{
UpdateChannel
}
from
"
vs/platform/update/node/updateIpc
"
;
import
{
IWorkbenchConstructionOptions
}
from
"
vs/workbench/workbench.web.api
"
;
import
{
Connection
,
ManagementConnection
,
ExtensionHostConnection
}
from
"
vs/server/src/connection
"
;
import
{
ExtensionEnvironmentChannel
,
FileProviderChannel
,
}
from
"
vs/server/src/channel
"
;
import
{
ExtensionEnvironmentChannel
,
FileProviderChannel
}
from
"
vs/server/src/channel
"
;
import
{
Connection
,
ExtensionHostConnection
,
ManagementConnection
}
from
"
vs/server/src/connection
"
;
import
{
TelemetryClient
}
from
"
vs/server/src/insights
"
;
import
{
get
NlsConfiguration
,
getLocaleFromConfig
}
from
"
vs/server/src/nls
"
;
import
{
get
LocaleFromConfig
,
getNlsConfiguration
}
from
"
vs/server/src/nls
"
;
import
{
Protocol
}
from
"
vs/server/src/protocol
"
;
import
{
TelemetryChannel
}
from
"
vs/server/src/telemetry
"
;
import
{
UpdateService
}
from
"
vs/server/src/update
"
;
import
{
AuthType
,
getMediaMime
,
getUriTransformer
,
localRequire
,
tmpdir
}
from
"
vs/server/src/util
"
;
import
{
RemoteExtensionLogFileName
}
from
"
vs/workbench/services/remote/common/remoteAgentService
"
;
import
{
IWorkbenchConstructionOptions
}
from
"
vs/workbench/workbench.web.api
"
;
export
enum
HttpCode
{
Ok
=
200
,
...
...
@@ -192,9 +196,9 @@ export abstract class Server {
try
{
const
payload
=
await
this
.
preHandleRequest
(
request
);
response
.
writeHead
(
payload
.
redirect
?
HttpCode
.
Redirect
:
payload
.
code
||
HttpCode
.
Ok
,
{
"
Cache-Control
"
:
"
max-age=86400
"
,
// TODO: ETag?
"
Content-Type
"
:
getMediaMime
(
payload
.
filePath
),
...(
payload
.
redirect
?
{
Location
:
this
.
withBase
(
request
,
payload
.
redirect
)
}
:
{}),
...(
request
.
headers
[
"
service-worker
"
]
?
{
"
Service-Worker-Allowed
"
:
this
.
options
.
basePath
+
"
/
"
}
:
{}),
...
payload
.
headers
,
});
response
.
end
(
payload
.
content
);
...
...
@@ -438,7 +442,7 @@ export class MainServer extends Server {
):
Promise
<
Response
>
{
switch
(
base
)
{
case
"
/
"
:
return
this
.
getRoot
(
request
,
parsedUrl
);
case
"
/resources
"
:
return
this
.
getResource
(
requestPath
);
case
"
/
vscode-
resources
"
:
return
this
.
getResource
(
requestPath
);
case
"
/webview
"
:
if
(
requestPath
.
indexOf
(
"
/vscode-resource
"
)
===
0
)
{
return
this
.
getResource
(
requestPath
.
replace
(
/^
\/
vscode-resource/
,
""
));
...
...
@@ -490,15 +494,19 @@ export class MainServer extends Server {
NLS_CONFIGURATION
:
await
getNlsConfiguration
(
locale
,
environment
.
userDataPath
),
};
Object
.
keys
(
options
).
forEach
((
key
)
=>
{
content
=
content
.
replace
(
`"{{
${
key
}
}}"`
,
`'
${
JSON
.
stringify
(
options
[
key
])}
'`
);
}
);
for
(
const
key
in
options
)
{
content
=
content
.
replace
(
`"{{
${
key
}
}}"`
,
`'
${
JSON
.
stringify
(
options
[
key
as
keyof
Options
])}
'`
);
}
content
=
content
.
replace
(
'
{{WEBVIEW_ENDPOINT}}
'
,
webviewEndpoint
);
return
{
content
,
filePath
};
}
private
async
connect
(
message
:
ConnectionTypeRequest
,
protocol
:
Protocol
):
Promise
<
void
>
{
if
(
product
.
commit
&&
message
.
commit
!==
product
.
commit
)
{
throw
new
Error
(
`Version mismatch (
${
message
.
commit
}
instead of
${
product
.
commit
}
)`
);
}
switch
(
message
.
desiredConnectionType
)
{
case
ConnectionType
.
ExtensionHost
:
case
ConnectionType
.
Management
:
...
...
@@ -552,16 +560,25 @@ export class MainServer extends Server {
}
private
async
initializeServices
(
args
:
ParsedArgs
):
Promise
<
void
>
{
const
router
=
new
StaticRouter
((
ctx
:
any
)
=>
ctx
.
clientId
===
"
renderer
"
);
const
environmentService
=
new
EnvironmentService
(
args
,
process
.
execPath
);
const
logService
=
new
SpdLogService
(
RemoteExtensionLogFileName
,
environmentService
.
logsPath
,
getLogLevel
(
environmentService
));
const
fileService
=
new
FileService
(
logService
);
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
logService
));
this
.
ipc
.
registerChannel
(
"
loglevel
"
,
new
LogLevelSetterChannel
(
logService
));
this
.
ipc
.
registerChannel
(
ExtensionHostDebugBroadcastChannel
.
ChannelName
,
new
ExtensionHostDebugBroadcastChannel
());
const
router
=
new
StaticRouter
((
ctx
:
any
)
=>
ctx
.
clientId
===
"
renderer
"
);
this
.
services
.
set
(
ILogService
,
logService
);
this
.
services
.
set
(
IEnvironmentService
,
environmentService
);
this
.
services
.
set
(
IConfigurationService
,
new
SyncDescriptor
(
ConfigurationService
,
[
environmentService
.
machineSettingsResource
]));
this
.
services
.
set
(
IRequestService
,
new
SyncDescriptor
(
RequestService
));
this
.
services
.
set
(
IFileService
,
fileService
);
this
.
services
.
set
(
IProductService
,
new
SyncDescriptor
(
ProductService
));
this
.
services
.
set
(
IDialogService
,
new
DialogChannelClient
(
this
.
ipc
.
getChannel
(
"
dialog
"
,
router
)));
this
.
services
.
set
(
IExtensionGalleryService
,
new
SyncDescriptor
(
ExtensionGalleryService
));
this
.
services
.
set
(
IExtensionManagementService
,
new
SyncDescriptor
(
ExtensionManagementService
));
if
(
!
environmentService
.
args
[
"
disable-telemetry
"
])
{
this
.
services
.
set
(
ITelemetryService
,
new
SyncDescriptor
(
TelemetryService
,
[{
appender
:
combinedAppender
(
...
...
@@ -582,8 +599,6 @@ export class MainServer extends Server {
}
else
{
this
.
services
.
set
(
ITelemetryService
,
NullTelemetryService
);
}
this
.
services
.
set
(
IDialogService
,
new
DialogChannelClient
(
this
.
ipc
.
getChannel
(
"
dialog
"
,
router
)));
this
.
services
.
set
(
IExtensionManagementService
,
new
SyncDescriptor
(
ExtensionManagementService
));
await
new
Promise
((
resolve
)
=>
{
const
instantiationService
=
new
InstantiationService
(
this
.
services
);
...
...
@@ -592,19 +607,23 @@ export class MainServer extends Server {
this
.
ipc
.
registerChannel
(
"
localizations
"
,
new
LocalizationsChannel
(
localizationService
));
instantiationService
.
invokeFunction
(()
=>
{
instantiationService
.
createInstance
(
LogsDataCleaner
);
this
.
ipc
.
registerChannel
(
REMOTE_FILE_SYSTEM_CHANNEL_NAME
,
new
FileProviderChannel
(
environmentService
,
logService
));
const
telemetryService
=
this
.
services
.
get
(
ITelemetryService
)
as
ITelemetryService
;
this
.
ipc
.
registerChannel
(
"
remoteextensionsenvironment
"
,
new
ExtensionEnvironmentChannel
(
environmentService
,
logService
,
telemetryService
));
const
extensionsService
=
this
.
services
.
get
(
IExtensionManagementService
)
as
IExtensionManagementService
;
const
telemetryService
=
this
.
services
.
get
(
ITelemetryService
)
as
ITelemetryService
;
const
extensionsChannel
=
new
ExtensionManagementChannel
(
extensionsService
,
(
context
)
=>
getUriTransformer
(
context
.
remoteAuthority
));
this
.
ipc
.
registerChannel
(
"
extensions
"
,
extensionsChannel
);
const
galleryService
=
this
.
services
.
get
(
IExtensionGalleryService
)
as
IExtensionGalleryService
;
const
galleryChannel
=
new
ExtensionGalleryChannel
(
galleryService
);
this
.
ipc
.
registerChannel
(
"
gallery
"
,
galleryChannel
);
const
extensionsEnvironmentChannel
=
new
ExtensionEnvironmentChannel
(
environmentService
,
logService
,
telemetryService
);
const
fileChannel
=
new
FileProviderChannel
(
environmentService
,
logService
);
const
requestChannel
=
new
RequestChannel
(
this
.
services
.
get
(
IRequestService
)
as
IRequestService
);
const
telemetryChannel
=
new
TelemetryChannel
(
telemetryService
);
this
.
ipc
.
registerChannel
(
"
telemetry
"
,
telemetryChannel
);
const
updateChannel
=
new
UpdateChannel
(
instantiationService
.
createInstance
(
UpdateService
));
this
.
ipc
.
registerChannel
(
"
extensions
"
,
extensionsChannel
);
this
.
ipc
.
registerChannel
(
"
remoteextensionsenvironment
"
,
extensionsEnvironmentChannel
);
this
.
ipc
.
registerChannel
(
"
request
"
,
requestChannel
);
this
.
ipc
.
registerChannel
(
"
telemetry
"
,
telemetryChannel
);
this
.
ipc
.
registerChannel
(
"
update
"
,
updateChannel
);
this
.
ipc
.
registerChannel
(
REMOTE_FILE_SYSTEM_CHANNEL_NAME
,
fileChannel
);
resolve
(
new
ErrorTelemetry
(
telemetryService
));
});
});
...
...
src/telemetry.ts
0 → 100644
浏览文件 @
ba728519
import
{
ITelemetryData
}
from
"
vs/base/common/actions
"
;
import
{
Event
}
from
"
vs/base/common/event
"
;
import
{
IChannel
,
IServerChannel
}
from
"
vs/base/parts/ipc/common/ipc
"
;
import
{
ClassifiedEvent
,
GDPRClassification
,
StrictPropertyCheck
}
from
"
vs/platform/telemetry/common/gdprTypings
"
;
import
{
ITelemetryInfo
,
ITelemetryService
}
from
"
vs/platform/telemetry/common/telemetry
"
;
export
class
TelemetryChannel
implements
IServerChannel
{
constructor
(
private
service
:
ITelemetryService
)
{}
listen
(
_
:
unknown
,
event
:
string
):
Event
<
any
>
{
throw
new
Error
(
`Invalid listen
${
event
}
`
);
}
call
(
_
:
unknown
,
command
:
string
,
args
?:
any
):
Promise
<
any
>
{
switch
(
command
)
{
case
"
publicLog
"
:
return
this
.
service
.
publicLog
(
args
[
0
],
args
[
1
],
args
[
2
]);
case
"
publicLog2
"
:
return
this
.
service
.
publicLog2
(
args
[
0
],
args
[
1
],
args
[
2
]);
case
"
setEnabled
"
:
return
Promise
.
resolve
(
this
.
service
.
setEnabled
(
args
[
0
]));
case
"
getTelemetryInfo
"
:
return
this
.
service
.
getTelemetryInfo
();
}
throw
new
Error
(
`Invalid call
${
command
}
`
);
}
}
export
class
TelemetryChannelClient
implements
ITelemetryService
{
_serviceBrand
:
any
;
constructor
(
private
readonly
channel
:
IChannel
)
{}
public
publicLog
(
eventName
:
string
,
data
?:
ITelemetryData
,
anonymizeFilePaths
?:
boolean
):
Promise
<
void
>
{
return
this
.
channel
.
call
(
"
publicLog
"
,
[
eventName
,
data
,
anonymizeFilePaths
]);
}
public
publicLog2
<
E
extends
ClassifiedEvent
<
T
>
=
never
,
T
extends
GDPRClassification
<
T
>
=
never
>
(
eventName
:
string
,
data
?:
StrictPropertyCheck
<
T
,
E
>
,
anonymizeFilePaths
?:
boolean
):
Promise
<
void
>
{
return
this
.
channel
.
call
(
"
publicLog2
"
,
[
eventName
,
data
,
anonymizeFilePaths
]);
}
public
setEnabled
(
value
:
boolean
):
void
{
this
.
channel
.
call
(
"
setEnable
"
,
[
value
]);
}
public
getTelemetryInfo
():
Promise
<
ITelemetryInfo
>
{
return
this
.
channel
.
call
(
"
getTelemetryInfo
"
);
}
public
get
isOptedIn
():
boolean
{
return
true
;
}
}
src/update.ts
浏览文件 @
ba728519
import
*
as
cp
from
"
child_process
"
;
import
*
as
os
from
"
os
"
;
import
*
as
path
from
"
path
"
;
import
{
Stream
}
from
"
stream
"
;
import
*
as
util
from
"
util
"
;
import
*
as
zlib
from
'
zlib
'
;
import
{
toVSBufferReadableStream
}
from
"
vs/base/common/buffer
"
;
import
{
CancellationToken
}
from
"
vs/base/common/cancellation
"
;
import
{
URI
}
from
"
vs/base/common/uri
"
;
import
*
as
pfs
from
"
vs/base/node/pfs
"
;
import
{
asJson
,
download
}
from
"
vs/base/node/request
"
;
import
{
IConfigurationService
}
from
"
vs/platform/configuration/common/configuration
"
;
import
{
IEnvironmentService
}
from
"
vs/platform/environment/common/environment
"
;
import
{
IFileService
}
from
"
vs/platform/files/common/files
"
;
import
{
ILogService
}
from
"
vs/platform/log/common/log
"
;
import
pkg
from
"
vs/platform/product/node/package
"
;
import
{
IRequestService
}
from
"
vs/platform/request/node
/request
"
;
import
{
State
,
UpdateType
,
StateType
,
AvailableForDownload
}
from
"
vs/platform/update/common/update
"
;
import
{
asJson
,
IRequestService
}
from
"
vs/platform/request/common
/request
"
;
import
{
AvailableForDownload
,
State
,
StateType
,
UpdateType
}
from
"
vs/platform/update/common/update
"
;
import
{
AbstractUpdateService
}
from
"
vs/platform/update/electron-main/abstractUpdateService
"
;
import
{
ipcMain
}
from
"
vs/server/src/ipc
"
;
import
{
extract
}
from
"
vs/server/src/marketplace
"
;
import
{
tmpdir
}
from
"
vs/server/src/util
"
;
import
{
extract
}
from
"
vs/server/src/tar
"
;
import
*
as
zlib
from
"
zlib
"
;
interface
IUpdate
{
name
:
string
;
...
...
@@ -30,7 +31,8 @@ export class UpdateService extends AbstractUpdateService {
@
IConfigurationService
configurationService
:
IConfigurationService
,
@
IEnvironmentService
environmentService
:
IEnvironmentService
,
@
IRequestService
requestService
:
IRequestService
,
@
ILogService
logService
:
ILogService
@
ILogService
logService
:
ILogService
,
@
IFileService
private
readonly
fileService
:
IFileService
,
)
{
super
(
null
,
configurationService
,
environmentService
,
requestService
,
logService
);
}
...
...
@@ -92,10 +94,13 @@ export class UpdateService extends AbstractUpdateService {
const
context
=
await
this
.
requestService
.
request
({
url
},
CancellationToken
.
None
);
// Decompress the gzip as we download. If the gzip encoding is set then
// the request service already does this.
// HACK: This uses knowledge of the internals of the request service.
if
(
target
!==
"
darwin
"
&&
context
.
res
.
headers
[
"
content-encoding
"
]
!==
"
gzip
"
)
{
context
.
stream
=
context
.
stream
.
pipe
(
zlib
.
createGunzip
());
const
stream
=
(
context
.
res
as
any
as
Stream
);
stream
.
removeAllListeners
();
context
.
stream
=
toVSBufferReadableStream
(
stream
.
pipe
(
zlib
.
createGunzip
()));
}
await
download
(
downloadPath
,
context
);
await
this
.
fileService
.
writeFile
(
URI
.
file
(
downloadPath
),
context
.
stream
);
await
extract
(
downloadPath
,
extractPath
,
undefined
,
CancellationToken
.
None
);
const
newBinary
=
path
.
join
(
extractPath
,
releaseName
,
"
code-server
"
);
if
(
!
pfs
.
exists
(
newBinary
))
{
...
...
src/upload.ts
浏览文件 @
ba728519
import
{
generateUuid
}
from
"
vs/base/common/uuid
"
;
import
{
DesktopDragAndDropData
}
from
"
vs/base/browser/ui/list/listView
"
;
import
{
VSBuffer
,
VSBufferReadable
}
from
"
vs/base/common/buffer
"
;
import
{
Emitter
,
Event
}
from
"
vs/base/common/event
"
;
import
{
VSBuffer
,
VSBufferReadableStream
}
from
"
vs/base/common/buffer
"
;
import
{
Disposable
}
from
"
vs/base/common/lifecycle
"
;
import
*
as
path
from
"
vs/base/common/path
"
;
import
{
URI
}
from
"
vs/base/common/uri
"
;
import
{
generateUuid
}
from
"
vs/base/common/uuid
"
;
import
{
IFileService
}
from
"
vs/platform/files/common/files
"
;
import
{
createDecorator
,
ServiceIdentifier
,
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
createDecorator
,
IInstantiationService
,
ServiceIdentifier
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
INotificationService
,
Severity
}
from
"
vs/platform/notification/common/notification
"
;
import
{
IProgress
,
IProgressStep
,
IProgressService
,
ProgressLocation
}
from
"
vs/platform/progress/common/progress
"
;
import
{
IProgress
,
IProgressService
,
IProgressStep
,
ProgressLocation
}
from
"
vs/platform/progress/common/progress
"
;
import
{
IWindowsService
}
from
"
vs/platform/windows/common/windows
"
;
import
{
IWorkspaceContextService
}
from
"
vs/platform/workspace/common/workspace
"
;
import
{
ExplorerItem
}
from
"
vs/workbench/contrib/files/common/explorerModel
"
;
import
{
IEditorGroup
}
from
"
vs/workbench/services/editor/common/editorGroupsService
"
;
import
{
IWorkspaceContextService
}
from
"
vs/platform/workspace/common/workspace
"
;
import
{
IWindowsService
}
from
"
vs/platform/windows/common/windows
"
;
import
{
IEditorService
}
from
"
vs/workbench/services/editor/common/editorService
"
;
export
const
IUploadService
=
createDecorator
<
IUploadService
>
(
"
uploadService
"
);
...
...
@@ -208,20 +207,15 @@ class Upload {
),
});
const
reader
=
new
Reader
(
file
);
reader
.
on
Data
(
(
data
)
=>
{
if
(
data
&&
data
.
l
ength
>
0
)
{
reader
.
on
(
"
data
"
,
(
data
)
=>
{
if
(
data
&&
data
.
byteL
ength
>
0
)
{
this
.
uploaded
+=
data
.
byteLength
;
}
});
reader
.
onAbort
(()
=>
{
const
remaining
=
file
.
size
-
reader
.
offset
;
if
(
remaining
>
0
)
{
this
.
uploaded
+=
remaining
;
}
});
this
.
uploadingFiles
.
set
(
filePath
,
reader
);
await
this
.
fileService
.
writeFile
(
tempUri
,
reader
);
if
(
reader
.
aborted
)
{
this
.
uploaded
+=
(
file
.
size
-
reader
.
offset
);
await
this
.
fileService
.
del
(
tempUri
);
}
else
{
await
this
.
fileService
.
move
(
tempUri
,
uri
,
true
);
...
...
@@ -292,17 +286,14 @@ class Upload {
}
}
class
Reader
implements
VSBufferReadable
{
class
Reader
implements
VSBufferReadable
Stream
{
private
_offset
=
0
;
private
readonly
size
=
32000
;
// ~32kb max while reading in the file.
private
readonly
_onData
=
new
Emitter
<
Uint8Array
|
null
>
();
public
readonly
onData
:
Event
<
Uint8Array
|
null
>
=
this
.
_onData
.
event
;
private
_aborted
=
false
;
private
readonly
_onAbort
=
new
Emitter
<
void
>
();
public
readonly
onAbort
:
Event
<
void
>
=
this
.
_onAbort
.
event
;
private
readonly
reader
=
new
FileReader
();
private
paused
=
true
;
private
buffer
?:
VSBuffer
;
private
callbacks
=
new
Map
<
string
,
Array
<
(...
args
:
any
[])
=>
void
>>
();
public
constructor
(
private
readonly
file
:
File
)
{
this
.
reader
.
addEventListener
(
"
load
"
,
this
.
onLoad
);
...
...
@@ -311,35 +302,71 @@ class Reader implements VSBufferReadable {
public
get
offset
():
number
{
return
this
.
_offset
;
}
public
get
aborted
():
boolean
{
return
this
.
_aborted
;
}
public
on
(
event
:
"
data
"
|
"
error
"
|
"
end
"
,
callback
:
(...
args
:
any
[])
=>
void
):
void
{
if
(
!
this
.
callbacks
.
has
(
event
))
{
this
.
callbacks
.
set
(
event
,
[]);
}
this
.
callbacks
.
get
(
event
)
!
.
push
(
callback
);
if
(
this
.
aborted
)
{
return
this
.
emit
(
"
error
"
,
new
Error
(
"
stream has been aborted
"
));
}
else
if
(
this
.
done
)
{
return
this
.
emit
(
"
error
"
,
new
Error
(
"
stream has ended
"
));
}
else
if
(
event
===
"
end
"
)
{
// Once this is being listened to we can safely start outputting data.
this
.
resume
();
}
}
public
abort
=
():
void
=>
{
this
.
_aborted
=
true
;
this
.
reader
.
abort
();
this
.
reader
.
removeEventListener
(
"
load
"
,
this
.
onLoad
);
this
.
_onAbort
.
fire
();
this
.
emit
(
"
end
"
);
}
public
pause
():
void
{
this
.
paused
=
true
;
}
public
read
=
async
():
Promise
<
VSBuffer
|
null
>
=>
{
return
new
Promise
<
VSBuffer
|
null
>
((
resolve
)
=>
{
const
disposables
=
[
this
.
onAbort
(()
=>
{
disposables
.
forEach
((
d
)
=>
d
.
dispose
());
resolve
(
null
);
}),
this
.
onData
((
data
)
=>
{
disposables
.
forEach
((
d
)
=>
d
.
dispose
());
resolve
(
data
&&
VSBuffer
.
wrap
(
data
));
}),
];
if
(
this
.
aborted
||
this
.
offset
>=
this
.
file
.
size
)
{
return
this
.
_onData
.
fire
(
null
);
public
resume
():
void
{
if
(
this
.
paused
)
{
this
.
paused
=
false
;
this
.
readNextChunk
();
}
}
public
destroy
():
void
{
this
.
abort
();
}
private
onLoad
=
():
void
=>
{
this
.
buffer
=
VSBuffer
.
wrap
(
new
Uint8Array
(
this
.
reader
.
result
as
ArrayBuffer
));
if
(
!
this
.
paused
)
{
this
.
readNextChunk
();
}
}
private
readNextChunk
():
void
{
if
(
this
.
buffer
)
{
this
.
_offset
+=
this
.
buffer
.
byteLength
;
this
.
emit
(
"
data
"
,
this
.
buffer
);
this
.
buffer
=
undefined
;
}
if
(
!
this
.
paused
)
{
// Could be paused during the data event.
if
(
this
.
done
)
{
this
.
emit
(
"
end
"
);
}
else
{
this
.
reader
.
readAsArrayBuffer
(
this
.
file
.
slice
(
this
.
offset
,
this
.
offset
+
this
.
size
));
}
const
slice
=
this
.
file
.
slice
(
this
.
offset
,
this
.
offset
+
this
.
size
);
this
.
_offset
+=
this
.
size
;
this
.
reader
.
readAsArrayBuffer
(
slice
);
});
}
}
private
emit
(
event
:
"
data
"
|
"
error
"
|
"
end
"
,
...
args
:
any
[]):
void
{
if
(
this
.
callbacks
.
has
(
event
))
{
this
.
callbacks
.
get
(
event
)
!
.
forEach
((
cb
)
=>
cb
(...
args
));
}
}
private
onLoad
=
()
=>
{
this
.
_onData
.
fire
(
new
Uint8Array
(
this
.
reader
.
result
as
ArrayBuffer
))
;
private
get
done
():
boolean
{
return
this
.
offset
>=
this
.
file
.
size
;
}
}
src/util.ts
浏览文件 @
ba728519
...
...
@@ -63,12 +63,12 @@ export const generatePassword = async (length: number = 24): Promise<string> =>
};
export
const
getMediaMime
=
(
filePath
?:
string
):
string
=>
{
return
filePath
&&
(
vsGetMediaMime
(
filePath
)
||
{
return
filePath
&&
(
vsGetMediaMime
(
filePath
)
||
(
<
{[
index
:
string
]:
string
}
>
{
"
.css
"
:
"
text/css
"
,
"
.html
"
:
"
text/html
"
,
"
.js
"
:
"
text/javascript
"
,
"
.json
"
:
"
application/json
"
,
}[
extname
(
filePath
)])
||
"
text/plain
"
;
}
)
[
extname
(
filePath
)])
||
"
text/plain
"
;
};
export
const
isWsl
=
async
():
Promise
<
boolean
>
=>
{
...
...
@@ -113,8 +113,16 @@ export const unpackExecutables = async (): Promise<void> => {
}
};
export
const
buildAllowedMessage
=
(
t
:
typeof
AuthType
):
string
=>
{
const
values
=
<
string
[]
>
Object
.
keys
(
t
).
map
((
k
)
=>
t
[
k
]);
export
const
enumToArray
=
(
t
:
any
):
string
[]
=>
{
const
values
=
<
string
[]
>
[];
for
(
const
k
in
t
)
{
values
.
push
(
t
[
k
]);
}
return
values
;
};
export
const
buildAllowedMessage
=
(
t
:
any
):
string
=>
{
const
values
=
enumToArray
(
t
);
return
`Allowed value
${
values
.
length
===
1
?
"
is
"
:
"
s are
"
}
${
values
.
map
((
t
)
=>
`'
${
t
}
'`
).
join
(
"
,
"
)}
`
;
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录