Add cli arguments
This commit is contained in:
parent
6a35ab1dc0
commit
770e0db7b8
@ -13,7 +13,8 @@ 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 { ILogService } from "vs/platform/log/common/log";
|
||||
import { IProductService } from "vs/platform/product/common/product";
|
||||
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 { ExtensionScanner, ExtensionScannerInput } from "vs/workbench/services/extensions/node/extensionPoints";
|
||||
import { DiskFileSystemProvider } from "vs/workbench/services/files/node/diskFileSystemProvider";
|
||||
@ -200,14 +201,13 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
|
||||
|
||||
private async scanExtensions(locale: string): Promise<IExtensionDescription[]> {
|
||||
const root = getPathFromAmdModule(require, "");
|
||||
const product = require.__$__nodeRequire(path.resolve(root, "../package.json")) as IProductService;
|
||||
|
||||
const translations = {}; // TODO: translations
|
||||
|
||||
// TODO: there is also this.environment.extensionDevelopmentLocationURI to look into.
|
||||
const scanBuiltin = async (): Promise<IExtensionDescription[]> => {
|
||||
const input = new ExtensionScannerInput(
|
||||
product.version, product.commit, locale, !!process.env.VSCODE_DEV,
|
||||
pkg.version, product.commit, locale, !!process.env.VSCODE_DEV,
|
||||
path.resolve(root, "../extensions"),
|
||||
true,
|
||||
false,
|
||||
@ -220,7 +220,7 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
|
||||
|
||||
const scanInstalled = async (): Promise<IExtensionDescription[]> => {
|
||||
const input = new ExtensionScannerInput(
|
||||
product.version, product.commit, locale, !!process.env.VSCODE_DEV,
|
||||
pkg.version, product.commit, locale, !!process.env.VSCODE_DEV,
|
||||
this.environment.extensionsPath, false, true, translations,
|
||||
);
|
||||
return ExtensionScanner.scanExtensions(input, this.log);
|
||||
|
65
cli.ts
Normal file
65
cli.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import * as os from "os";
|
||||
import { validatePaths } from "vs/code/node/paths";
|
||||
import { parseMainProcessArgv } from "vs/platform/environment/node/argvHelper";
|
||||
import { ParsedArgs } from "vs/platform/environment/common/environment";
|
||||
import { buildHelpMessage, buildVersionMessage } from "vs/platform/environment/node/argv";
|
||||
import product from "vs/platform/product/node/product";
|
||||
import pkg from "vs/platform/product/node/package";
|
||||
import { MainServer, WebviewServer } from "vs/server/server";
|
||||
import "vs/server/tar";
|
||||
|
||||
interface IMainCli {
|
||||
main: (argv: ParsedArgs) => Promise<void>;
|
||||
}
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
const args = validatePaths(parseMainProcessArgv(process.argv));
|
||||
|
||||
if (!product.extensionsGallery) {
|
||||
product.extensionsGallery = {
|
||||
serviceUrl: process.env.SERVICE_URL || "https://v1.extapi.coder.com",
|
||||
itemUrl: process.env.ITEM_URL || "",
|
||||
controlUrl: "",
|
||||
recommendationsUrl: "",
|
||||
};
|
||||
}
|
||||
|
||||
if (args.help) {
|
||||
const executable = `${product.applicationName}${os.platform() === "win32" ? ".exe" : ""}`;
|
||||
return console.log(buildHelpMessage(product.nameLong, executable, pkg.version));
|
||||
}
|
||||
|
||||
if (args.version) {
|
||||
return console.log(buildVersionMessage(pkg.version, product.commit));
|
||||
}
|
||||
|
||||
const shouldSpawnCliProcess = (): boolean => {
|
||||
return !!args["install-source"]
|
||||
|| !!args["list-extensions"]
|
||||
|| !!args["install-extension"]
|
||||
|| !!args["uninstall-extension"]
|
||||
|| !!args["locate-extension"]
|
||||
|| !!args["telemetry"];
|
||||
};
|
||||
|
||||
if (shouldSpawnCliProcess()) {
|
||||
const cli = await new Promise<IMainCli>((c, e) => require(["vs/code/node/cliProcessMain"], c, e));
|
||||
await cli.main(args);
|
||||
// There is some WriteStream instance keeping it open so force an exit.
|
||||
return process.exit(0);
|
||||
}
|
||||
|
||||
const webviewServer = new WebviewServer();
|
||||
const server = new MainServer(webviewServer, args);
|
||||
// The main server inserts webview server address to the root HTML, so we'll
|
||||
// need to wait for it to listen otherwise the address will be null.
|
||||
await webviewServer.listen(8444);
|
||||
await server.listen(8443);
|
||||
console.log(`Main server serving ${server.address}`);
|
||||
console.log(`Webview server serving ${webviewServer.address}`);
|
||||
};
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
12
entry.ts
12
entry.ts
@ -1,12 +0,0 @@
|
||||
import { MainServer, WebviewServer } from "./server";
|
||||
|
||||
const webviewServer = new WebviewServer();
|
||||
const server = new MainServer(webviewServer);
|
||||
webviewServer.listen(8444).then(async () => {
|
||||
await server.listen(8443);
|
||||
console.log(`Main server serving ${server.address}`);
|
||||
console.log(`Webview server serving ${webviewServer.address}`);
|
||||
}).catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
2
main.js
2
main.js
@ -1 +1 @@
|
||||
require("../../bootstrap-amd").load("vs/server/entry");
|
||||
require("../../bootstrap-amd").load("vs/server/cli");
|
||||
|
@ -5,6 +5,13 @@
|
||||
"build": "echo TODO && exit 1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/tar-stream": "^1.6.1",
|
||||
"nodemon": "^1.19.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tar-stream": "^2.1.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/node": "^10.12.12"
|
||||
}
|
||||
}
|
||||
|
16
server.ts
16
server.ts
@ -5,16 +5,13 @@ import * as path from "path";
|
||||
import * as util from "util";
|
||||
import * as url from "url";
|
||||
|
||||
import { getPathFromAmdModule } from "vs/base/common/amd";
|
||||
import { Emitter } from "vs/base/common/event";
|
||||
import { sanitizeFilePath } from "vs/base/common/extpath";
|
||||
import { getMediaMime } from "vs/base/common/mime";
|
||||
import { extname } from "vs/base/common/path";
|
||||
import { UriComponents, URI } from "vs/base/common/uri";
|
||||
import { IPCServer, ClientConnectionEvent } from "vs/base/parts/ipc/common/ipc";
|
||||
import { validatePaths } from "vs/code/node/paths";
|
||||
import { LogsDataCleaner } from "vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner";
|
||||
import { parseMainProcessArgv } from "vs/platform/environment/node/argvHelper";
|
||||
import { IEnvironmentService, ParsedArgs } from "vs/platform/environment/common/environment";
|
||||
import { EnvironmentService } from "vs/platform/environment/node/environmentService";
|
||||
import { InstantiationService } from "vs/platform/instantiation/common/instantiationService";
|
||||
@ -23,6 +20,7 @@ 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 product from "vs/platform/product/node/product";
|
||||
import { ConnectionType, ConnectionTypeRequest } from "vs/platform/remote/common/remoteAgentConnection";
|
||||
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from "vs/platform/remote/common/remoteAgentFileSystemChannel";
|
||||
import { RemoteExtensionLogFileName } from "vs/workbench/services/remote/common/remoteAgentService";
|
||||
@ -123,7 +121,7 @@ export class MainServer extends Server {
|
||||
|
||||
private readonly services = new ServiceCollection();
|
||||
|
||||
public constructor(private readonly webviewServer: WebviewServer) {
|
||||
public constructor(private readonly webviewServer: WebviewServer, args: ParsedArgs) {
|
||||
super();
|
||||
|
||||
this.server.on("upgrade", async (request, socket) => {
|
||||
@ -134,10 +132,6 @@ export class MainServer extends Server {
|
||||
protocol.dispose(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async listen(port: number): Promise<void> {
|
||||
const args = validatePaths(parseMainProcessArgv(process.argv));
|
||||
|
||||
const environmentService = new EnvironmentService(args, process.execPath);
|
||||
this.services.set(IEnvironmentService, environmentService);
|
||||
@ -163,8 +157,6 @@ export class MainServer extends Server {
|
||||
new ExtensionEnvironmentChannel(environmentService, logService),
|
||||
);
|
||||
});
|
||||
|
||||
await super.listen(port);
|
||||
}
|
||||
|
||||
protected async handleRequest(
|
||||
@ -203,9 +195,7 @@ export class MainServer extends Server {
|
||||
REMOTE_USER_DATA_URI: transformer.transformOutgoing(
|
||||
(this.services.get(IEnvironmentService) as EnvironmentService).webUserDataHome,
|
||||
),
|
||||
PRODUCT_CONFIGURATION: require.__$__nodeRequire(
|
||||
path.resolve(getPathFromAmdModule(require, ""), "../product.json"),
|
||||
),
|
||||
PRODUCT_CONFIGURATION: product,
|
||||
CONNECTION_AUTH_TOKEN: "",
|
||||
};
|
||||
|
||||
|
44
tar.ts
44
tar.ts
@ -1,10 +1,5 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from "vs/nls";
|
||||
import * as vszip from "vszip";
|
||||
import * as vszip from "vs/base/node/zip";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as tarStream from "tar-stream";
|
||||
@ -12,6 +7,10 @@ import { promisify } from "util";
|
||||
import { CancellationToken } from "vs/base/common/cancellation";
|
||||
import { mkdirp } from "vs/base/node/pfs";
|
||||
|
||||
// We will be overriding these, so keep a reference to the original.
|
||||
const vszipExtract = vszip.extract;
|
||||
const vszipBuffer = vszip.buffer;
|
||||
|
||||
export interface IExtractOptions {
|
||||
overwrite?: boolean;
|
||||
|
||||
@ -29,8 +28,8 @@ export interface IFile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the standard VS Code behavior for zipping
|
||||
* extensions to use the TAR format instead of ZIP.
|
||||
* Override the standard VS Code behavior for zipping extensions to use the TAR
|
||||
* format instead of ZIP.
|
||||
*/
|
||||
export const zip = (tarPath: string, files: IFile[]): Promise<string> => {
|
||||
return new Promise<string>((c, e): void => {
|
||||
@ -63,10 +62,9 @@ export const zip = (tarPath: string, files: IFile[]): Promise<string> => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the standard VS Code behavior for extracting
|
||||
* archives, to first attempt to process the archive as a TAR
|
||||
* and then fallback on the original implementation, for processing
|
||||
* ZIPs.
|
||||
* Override the standard VS Code behavior for extracting archives to first
|
||||
* attempt to process the archive as a TAR and then fall back to the original
|
||||
* implementation for processing ZIPs.
|
||||
*/
|
||||
export const extract = (archivePath: string, extractPath: string, options: IExtractOptions = {}, token: CancellationToken): Promise<void> => {
|
||||
return new Promise<void>((c, e): void => {
|
||||
@ -76,15 +74,15 @@ export const extract = (archivePath: string, extractPath: string, options: IExtr
|
||||
|
||||
return;
|
||||
}
|
||||
vszip.extract(archivePath, extractPath, options, token).then(c).catch(e);
|
||||
vszipExtract(archivePath, extractPath, options, token).then(c).catch(e);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the standard VS Code behavior for buffering
|
||||
* archives, to first process the Buffer as a TAR and then
|
||||
* fallback on the original implementation, for processing ZIPs.
|
||||
* Override the standard VS Code behavior for buffering archives to first
|
||||
* process the Buffer as a TAR and then fall back to the original
|
||||
* implementation for processing ZIPs.
|
||||
*/
|
||||
export const buffer = (targetPath: string, filePath: string): Promise<Buffer> => {
|
||||
return new Promise<Buffer>((c, e): void => {
|
||||
@ -104,16 +102,16 @@ export const buffer = (targetPath: string, filePath: string): Promise<Buffer> =>
|
||||
|
||||
return;
|
||||
}
|
||||
vszip.buffer(targetPath, filePath).then(c).catch(e);
|
||||
vszipBuffer(targetPath, filePath).then(c).catch(e);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the standard VS Code behavior for extracting assets
|
||||
* from archive Buffers to use the TAR format instead of ZIP.
|
||||
* Override the standard VS Code behavior for extracting assets from archive
|
||||
* Buffers to use the TAR format instead of ZIP.
|
||||
*/
|
||||
export const extractAssets = (tarPath: string, match: RegExp, callback: (path: string, data: Buffer) => void): Promise<void> => {
|
||||
const extractAssets = (tarPath: string, match: RegExp, callback: (path: string, data: Buffer) => void): Promise<void> => {
|
||||
return new Promise<void>(async (c, e): Promise<void> => {
|
||||
try {
|
||||
const buffer = await promisify(fs.readFile)(tarPath);
|
||||
@ -217,3 +215,9 @@ const extractTar = (tarPath: string, targetPath: string, options: IExtractOption
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Override original functionality so we can use tar instead of zip.
|
||||
const target = vszip as typeof vszip;
|
||||
target.zip = zip;
|
||||
target.extract = extract;
|
||||
target.buffer = buffer;
|
||||
|
62
yarn.lock
62
yarn.lock
@ -2,6 +2,18 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@*", "@types/node@^10.12.12":
|
||||
version "10.14.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.10.tgz#e491484c6060af8d461e12ec81c0da8a3282b8de"
|
||||
integrity sha512-V8wj+w2YMNvGuhgl/MA5fmTxgjmVHVoasfIaxMMZJV6Y8Kk+Ydpi1z2whoShDCJ2BuNVoqH/h1hrygnBxkrw/Q==
|
||||
|
||||
"@types/tar-stream@^1.6.1":
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/tar-stream/-/tar-stream-1.6.1.tgz#67d759068ff781d976cad978893bb7a334ec8809"
|
||||
integrity sha512-pYCDOPuRE+4tXFk1rSMYiuI+kSrXiJ4av1bboQbkcEBA2rqwEWfIn9kdMSH+5nYu58WksHuxwx+7kVbtg0Le7w==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
||||
@ -110,6 +122,13 @@ binary-extensions@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14"
|
||||
integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==
|
||||
|
||||
bl@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88"
|
||||
integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==
|
||||
dependencies:
|
||||
readable-stream "^3.0.1"
|
||||
|
||||
boxen@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
|
||||
@ -376,6 +395,13 @@ duplexer3@^0.1.4:
|
||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
||||
integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
|
||||
|
||||
end-of-stream@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
|
||||
integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
@ -458,6 +484,11 @@ fragment-cache@^0.2.1:
|
||||
dependencies:
|
||||
map-cache "^0.2.2"
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
fs-minipass@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
|
||||
@ -1120,7 +1151,7 @@ object.pick@^1.3.0:
|
||||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
once@^1.3.0:
|
||||
once@^1.3.0, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
@ -1238,6 +1269,15 @@ readable-stream@^2.0.2, readable-stream@^2.0.6:
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^3.0.1, readable-stream@^3.1.1:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc"
|
||||
integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readdirp@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
|
||||
@ -1466,6 +1506,13 @@ string-width@^1.0.1:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
|
||||
integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
@ -1504,6 +1551,17 @@ supports-color@^5.2.0, supports-color@^5.3.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
tar-stream@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3"
|
||||
integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==
|
||||
dependencies:
|
||||
bl "^3.0.0"
|
||||
end-of-stream "^1.4.1"
|
||||
fs-constants "^1.0.0"
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^3.1.1"
|
||||
|
||||
tar@^4:
|
||||
version "4.4.8"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d"
|
||||
@ -1636,7 +1694,7 @@ use@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
|
||||
integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
Reference in New Issue
Block a user