diff --git a/package.json b/package.json
index 9c35d6f4..e6cb3503 100644
--- a/package.json
+++ b/package.json
@@ -79,10 +79,6 @@
"default": false,
"description": "Disable notification on long running tasks."
},
- "truffle-vscode.storageAccount.name": {
- "type": "string",
- "scope": "Storage Account name"
- },
"truffle-vscode.coreSDK": {
"type": "string",
"scope": "Core SDK for extensions backend",
@@ -764,6 +760,8 @@
"@commitlint/cli": "^17.0.3",
"@commitlint/config-conventional": "^17.0.3",
"@types/big.js": "^6.1.2",
+ "@types/chai": "^4.3.4",
+ "@types/chai-as-promised": "^7.1.5",
"@types/copy-webpack-plugin": "^8.0.1",
"@types/download": "^6.2.4",
"@types/estree": "^0.0.52",
@@ -780,7 +778,7 @@
"@types/rewire": "^2.5.28",
"@types/rimraf": "^3.0.2",
"@types/semver": "^6.0.0",
- "@types/sinon": "^7.0.11",
+ "@types/sinon": "^10.0.13",
"@types/source-map": "^0.5.2",
"@types/uuid": "^3.4.4",
"@types/vscode": "1.66.0",
@@ -789,6 +787,8 @@
"@vscode/debugadapter": "^1.55.1",
"@vscode/debugprotocol": "^1.55.1",
"@vscode/test-electron": "^2.1.3",
+ "chai": "^4.3.7",
+ "chai-as-promised": "^7.1.1",
"copy-webpack-plugin": "^10.0.0",
"copyfiles": "^2.4.1",
"decache": "^4.5.1",
@@ -797,13 +797,13 @@
"husky": "^8.0.1",
"istanbul": "^0.4.5",
"lint-staged": "^8.2.0",
- "mocha": "^6.2.3",
+ "mocha": "^10.0.0",
"mockery": "^2.1.0",
"prettier": "2.7.1",
"pretty-quick": "^3.1.3",
"remap-istanbul": "^0.13.0",
"rewire": "^4.0.1",
- "sinon": "^7.3.2",
+ "sinon": "^14.0.2",
"truffle": "^5.5.30",
"ts-loader": "9.3.1",
"ts-node": "^10.8.1",
diff --git a/resources/ganache/assets/icons/contract.svg b/resources/ganache/assets/icons/contract.svg
index b2912dd9..0050757d 100644
--- a/resources/ganache/assets/icons/contract.svg
+++ b/resources/ganache/assets/icons/contract.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
diff --git a/resources/ganache/assets/icons/events.svg b/resources/ganache/assets/icons/events.svg
index c55dceb4..7bc1e825 100644
--- a/resources/ganache/assets/icons/events.svg
+++ b/resources/ganache/assets/icons/events.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
diff --git a/src/Constants.ts b/src/Constants.ts
index 12c6fa18..186942ce 100644
--- a/src/Constants.ts
+++ b/src/Constants.ts
@@ -18,6 +18,11 @@ export enum RequiredApps {
dashboard = 'dashboard',
}
+export enum OptionalApps {
+ hardhat = 'hardhat',
+}
+export type AppTypes = RequiredApps | OptionalApps;
+
export enum NotificationOptions {
error = 'error',
info = 'info',
@@ -119,6 +124,10 @@ export class Constants {
max: '',
min: '5.5.0',
},
+ [OptionalApps.hardhat]: {
+ max: '',
+ min: '2.9.0',
+ },
};
public static telemetryEvents = {
@@ -607,6 +616,8 @@ export class Constants {
FetchingBoxesHasFailed: 'An error occurred while fetching boxes',
ContractFolderNotExists: 'There is no contract directory in this workspace',
UriHandlerError: 'Badly formatted. Ensure that the command and arguments are described correctly',
+ HHNoDefaultDeploy:
+ 'Hardhat has no default deploy command. Consider using the HardHat Deploy Plugin: [hardhat-deploy](https://github.com/wighawag/hardhat-deploy)',
};
public static informationMessage = {
@@ -678,11 +689,11 @@ export class Constants {
};
public static userSettings = {
coreSdkSettingsKey: 'truffle-vscode.coreSDK',
- storageAccountUserSettingsKey: 'truffle-vscode.storageAccount.name',
};
public static coreSdk = {
truffle: 'Truffle',
+ hardhat: 'Hardhat',
};
public static initialize(context: ExtensionContext) {
diff --git a/src/Output.ts b/src/Output.ts
index ab05cb81..bab4e135 100644
--- a/src/Output.ts
+++ b/src/Output.ts
@@ -13,6 +13,8 @@ export enum OutputLabel {
requirements = 'Truffle: Requirements',
telemetryClient = 'Truffle: Telemetry Client',
treeManager = 'Truffle: Service Tree Manager',
+ sdkCoreCommands = 'Truffle: SDK Commands',
+ hardhatCommands = 'Truffle: Hardhat Commands',
}
export class Output {
diff --git a/src/commands/DebuggerCommands.ts b/src/commands/DebuggerCommands.ts
index 44584e3d..c08cc5b8 100644
--- a/src/commands/DebuggerCommands.ts
+++ b/src/commands/DebuggerCommands.ts
@@ -8,8 +8,9 @@ import {DEBUG_TYPE} from '@/debugAdapter/constants/debugAdapter';
import {DebugNetwork} from '@/debugAdapter/debugNetwork';
import {TransactionProvider} from '@/debugAdapter/transaction/transactionProvider';
import {Web3Wrapper} from '@/debugAdapter/web3Wrapper';
-import {getTruffleWorkspace, getPathByPlatform} from '@/helpers/workspace';
+import {getWorkspaceForUri} from '@/helpers/AbstractWorkspace';
import {showInputBox, showQuickPick} from '@/helpers/userInteraction';
+import {getPathByPlatform} from '@/helpers/WorkspaceHelpers';
import {Telemetry} from '@/TelemetryClient';
import {DebuggerTypes} from '@/debugAdapter/models/debuggerTypes';
@@ -19,7 +20,7 @@ export namespace DebuggerCommands {
export async function startSolidityDebugger() {
Telemetry.sendEvent('DebuggerCommands.startSolidityDebugger.commandStarted');
- const workspaceUri = (await getTruffleWorkspace()).workspace;
+ const workspaceUri = (await getWorkspaceForUri()).workspace;
const workingDirectory = getPathByPlatform(workspaceUri);
const debugNetwork = new DebugNetwork(workingDirectory);
await debugNetwork.load();
@@ -95,7 +96,7 @@ async function getQuickPickItems(txProvider: TransactionProvider) {
/**
* Responsible for starting the Solidity debugger with the given arguments.
- *
+ *
@param args The `DebugArgs` to initialize the `DebugSession`.
*/
export async function startDebugging(args: DebuggerTypes.DebugArgs): Promise {
diff --git a/src/commands/HardhatCommands.ts b/src/commands/HardhatCommands.ts
new file mode 100644
index 00000000..33beeb9f
--- /dev/null
+++ b/src/commands/HardhatCommands.ts
@@ -0,0 +1,44 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+import {Constants, NotificationOptions, OptionalApps} from '@/Constants';
+
+import {outputCommandHelper} from '@/helpers';
+import {required} from '@/helpers/required';
+import {showIgnorableNotification, showNotification} from '@/helpers/userInteraction';
+import {AbstractWorkspace} from '@/helpers/AbstractWorkspace';
+import {Output, OutputLabel} from '@/Output';
+import {Telemetry} from '@/TelemetryClient';
+import {commands, Uri} from 'vscode';
+
+export async function buildContracts(ws: AbstractWorkspace, uri?: Uri): Promise {
+ Telemetry.sendEvent('HardhatCommands.buildContracts.commandStarted');
+ if (!(await required.checkAppsSilentForUri(ws.workspace, OptionalApps.hardhat))) {
+ Telemetry.sendEvent('HardhatCommands.buildContracts.hardhatInstallationMissing');
+ await showNotification({
+ message: 'Hardhat is not installed, please install to continue...',
+ type: NotificationOptions.error,
+ });
+ // await required.installHardhat(required.Scope.locally);
+ return;
+ }
+
+ const workspaceDir = ws.workspace.fsPath;
+
+ Output.outputLine(OutputLabel.hardhatCommands, `compiling: ${JSON.stringify(uri)} : ${workspaceDir}`);
+ const args: string[] = [OptionalApps.hardhat, 'compile'];
+
+ // hardhat will compile all contracts, not one specifically.
+ Output.outputLine(
+ OutputLabel.hardhatCommands,
+ `Building: ${args} DIR: ${workspaceDir} Workspace: ${JSON.stringify(ws)} `
+ );
+
+ await showIgnorableNotification(Constants.statusBarMessages.buildingContracts, async () => {
+ Output.show();
+ await outputCommandHelper.executeCommand(workspaceDir, 'npx', args.join(' '));
+ commands.executeCommand('truffle-vscode.views.deployments.refresh');
+
+ Telemetry.sendEvent('HardhatCommands.buildContracts.commandFinished');
+ });
+}
diff --git a/src/commands/SdkCoreCommands.ts b/src/commands/SdkCoreCommands.ts
index 104c0956..fda64199 100644
--- a/src/commands/SdkCoreCommands.ts
+++ b/src/commands/SdkCoreCommands.ts
@@ -1,20 +1,39 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
-import {Memento, window, Uri} from 'vscode';
-import {Constants} from '@/Constants';
-import {userSettings} from '../helpers';
-import {IExtensionAdapter, TruffleExtensionAdapter} from '@/services/extensionAdapter';
+import {getWorkspaceForUri, WorkspaceType} from '@/helpers/AbstractWorkspace';
+import {Output, OutputLabel} from '@/Output';
+
+import {
+ HardHatExtensionAdapter,
+ IExtensionAdapter,
+ TruffleExtensionAdapter,
+ UnknownExtensionAdapter,
+} from '@/services/extensionAdapter';
+import {Uri, window} from 'vscode';
class SdkCoreCommands {
- private extensionAdapter!: IExtensionAdapter;
-
- public async initialize(_globalState: Memento): Promise {
- const sdk = await this.getCoreSdk();
- this.extensionAdapter = this.getExtensionAdapter(sdk.userValue ? sdk.userValue : sdk.defaultValue);
- this.extensionAdapter.validateExtension().catch((error) => {
- window.showErrorMessage(error.message);
- });
+ private extensionAdapters = new Map();
+
+ public getExtensionAdapter(sdkVal: WorkspaceType): IExtensionAdapter | undefined {
+ if (this.extensionAdapters.has(sdkVal)) {
+ return this.extensionAdapters.get(sdkVal);
+ }
+ // let's initialise it otherwise
+ const adapter = this.initExtensionAdapter(sdkVal);
+ adapter.validateExtension().then(
+ (_) => {
+ Output.outputLine(
+ OutputLabel.sdkCoreCommands,
+ `Configuration Initialized. SdkCoreProvider: ${adapter.constructor.name}`
+ );
+ },
+ (error) => {
+ window.showErrorMessage(error.message);
+ }
+ );
+ this.extensionAdapters.set(sdkVal, adapter);
+ return adapter;
}
/**
@@ -23,7 +42,10 @@ class SdkCoreCommands {
* @param contractUri if provided, it is the `Uri` of the smart contract to be compiled.
*/
public async build(contractUri?: Uri): Promise {
- return this.extensionAdapter.build(contractUri);
+ const ws = await getWorkspaceForUri(contractUri);
+ const buildUri = contractUri ? contractUri : ws.workspace;
+ const adapter = this.getExtensionAdapter(ws.workspaceType);
+ return adapter!.build(ws, buildUri);
}
/**
@@ -32,17 +54,20 @@ class SdkCoreCommands {
* @param contractUri FIXME: Is this used?
*/
public async deploy(contractUri?: Uri): Promise {
- return this.extensionAdapter.deploy(contractUri);
+ const ws = await getWorkspaceForUri(contractUri);
+ const deployUri = contractUri ? contractUri : ws.workspace;
+ const adapter = this.getExtensionAdapter(ws.workspaceType);
+ return adapter!.deploy(ws, deployUri);
}
- private async getCoreSdk() {
- return userSettings.getConfigurationAsync(Constants.userSettings.coreSdkSettingsKey);
- }
-
- private getExtensionAdapter(sdk: string): IExtensionAdapter {
+ private initExtensionAdapter(sdk: WorkspaceType): IExtensionAdapter {
switch (sdk) {
- default:
+ case WorkspaceType.HARDHAT:
+ return new HardHatExtensionAdapter();
+ case WorkspaceType.TRUFFLE:
return new TruffleExtensionAdapter();
+ default:
+ return new UnknownExtensionAdapter();
}
}
}
diff --git a/src/commands/TruffleCommands.ts b/src/commands/TruffleCommands.ts
index 93a53bb2..311588d4 100644
--- a/src/commands/TruffleCommands.ts
+++ b/src/commands/TruffleCommands.ts
@@ -14,7 +14,7 @@ import {getTruffleWorkspace} from '@/helpers/workspace';
import {required} from '@/helpers/required';
import {showQuickPick, showConfirmPaidOperationDialog, showIgnorableNotification} from '@/helpers/userInteraction';
-import {getPathByPlatform} from '@/helpers/workspace';
+import {getPathByPlatform} from '@/helpers/WorkspaceHelpers';
import {IDeployDestination, ItemType} from '@/Models';
import {NetworkForContractItem} from '@/Models/QuickPickItems';
@@ -573,7 +573,7 @@ async function readCompiledContract(uri: Uri): Promise {
return JSON.parse(data.toString());
}
-function ensureFileIsContractJson(filePath: string) {
+function ensureFileIsContractJson(filePath: string): void {
if (path.extname(filePath) !== Constants.contract.configuration.extension.json) {
const error = new Error(Constants.errorMessageStrings.InvalidContract);
Telemetry.sendException(error);
diff --git a/src/extension.ts b/src/extension.ts
index 5e2e2b67..542b35ca 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -38,7 +38,7 @@ import {registerHelpView} from './views/HelpView';
import {OpenUrlTreeItem} from './views/lib/OpenUrlTreeItem';
import {registerGanacheDetails} from './pages/GanacheDetails';
import {registerLogView} from './views/LogView';
-import {saveTextDocument} from './helpers/workspace';
+import {saveTextDocument} from './helpers/WorkspaceHelpers';
import {StatusBarItems} from './Models/StatusBarItems/Contract';
import {UriHandlerController} from './helpers/uriHandlerController';
import {Output} from './Output';
@@ -78,7 +78,6 @@ export async function activate(context: ExtensionContext) {
MnemonicRepository.initialize(context.globalState);
TreeManager.initialize(context.globalState);
TreeService.initialize('truffle-vscode.truffle');
- await sdkCoreCommands.initialize(context.globalState);
// Starts the status bar item for automatic deploy
const contractStatusBarItem = new StatusBarItems.Contract(context.globalState);
@@ -231,11 +230,12 @@ export async function activate(context: ExtensionContext) {
//#endregion
//#region workspace subscriptions
- const changeCoreSdkConfigurationListener = workspace.onDidChangeConfiguration(async (event) => {
- if (event.affectsConfiguration(Constants.userSettings.coreSdkSettingsKey)) {
- await sdkCoreCommands.initialize(context.globalState);
- }
- });
+ // I think this isn't needed anymore.
+ // const changeCoreSdkConfigurationListener = workspace.onDidChangeConfiguration(async (event) => {
+ // if (event.affectsConfiguration(Constants.userSettings.coreSdkSettingsKey)) {
+ // await sdkCoreCommands.initialize(context.globalState);
+ // }
+ // });
const didSaveTextDocumentListener = workspace.onDidSaveTextDocument(async (event) => {
// Calls the action that listens for the save files event
await saveTextDocument(context.globalState, event);
@@ -274,7 +274,6 @@ export async function activate(context: ExtensionContext) {
signInToInfuraAccount,
signOutOfInfuraAccount,
showProjectsFromInfuraAccount,
- changeCoreSdkConfigurationListener,
didSaveTextDocumentListener,
// new view - main views
fileExplorerView,
diff --git a/src/helpers/AbstractWorkspace.ts b/src/helpers/AbstractWorkspace.ts
new file mode 100644
index 00000000..a9e94e48
--- /dev/null
+++ b/src/helpers/AbstractWorkspace.ts
@@ -0,0 +1,165 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+import {Constants} from '@/Constants';
+import {showQuickPick} from '@/helpers/userInteraction';
+import {Telemetry} from '@/TelemetryClient';
+import glob from 'glob';
+import * as path from 'path';
+import {Uri, workspace} from 'vscode';
+
+/**
+ * The [glob](https://github.com/isaacs/node-glob#glob-primer) pattern to match Truffle/Other config file names.
+ */
+export const TRUFFLE_CONFIG_GLOB = 'truffle-config*.js';
+export const HARDHAT_CONFIG_GLOB = 'hardhat.config*.{js,ts}';
+
+class ResolverConfig {
+ constructor(public type: WorkspaceType, public glob: string) {}
+
+ async resolvePath(_uri: Uri): Promise {
+ return undefined;
+ }
+}
+
+export enum WorkspaceType {
+ TRUFFLE = 'Truffle',
+ HARDHAT = 'Hardhat',
+ UNKNOWN = 'Unknown',
+}
+
+export const WorkspaceResolvers: Array = [
+ new ResolverConfig(WorkspaceType.TRUFFLE, TRUFFLE_CONFIG_GLOB),
+ new ResolverConfig(WorkspaceType.HARDHAT, HARDHAT_CONFIG_GLOB),
+];
+
+export class AbstractWorkspace {
+ /**
+ * Create an {WorkspaceType.UNKNOWN} workspace. Usually a root with no known
+ * framework in it.
+ *
+ * @param path - the folder root path
+ */
+ static createUnknownWorkspace(path: Uri): AbstractWorkspace {
+ return new AbstractWorkspace(path, '', WorkspaceType.UNKNOWN);
+ }
+
+ /**
+ * Create a workspace from a config path. Will try to adapt the path to get workspace root.
+ * @param configPath - The config file, which can drive things later on.
+ * @param type - The {WorkspaceType} type. This will generally not be an {WorkspaceType.UNKNOWN}
+ * @throws Error when you attempt to use {WorkspaceType.UNKNOWN} as the type.
+ */
+ static createWorkspaceFromConfigPath(configPath: string, type: WorkspaceType): AbstractWorkspace {
+ if (type === WorkspaceType.UNKNOWN) throw new Error('Cannot use UNKNOWN workspace type with this constructor.');
+ const workspacePath = Uri.parse(path.dirname(configPath));
+ return new AbstractWorkspace(workspacePath, configPath, type);
+ }
+
+ /**
+ * Constructor to derive the workspace based on either the dirName (which is the root) or the config
+ * file location (from the glob). This also allows us to make Unknown or generic workspace types
+ * to help with config/reconciling commands etc.
+ *
+ * @param workspaceUri - the directory this workspace is in
+ * @param configPath - the path (optionally) to the config
+ * @param workspaceType - the type of workspace we are dealing with.
+ * @private - use the static constructors above.
+ */
+ private constructor(workspaceUri: Uri, configPath: string, public readonly workspaceType: WorkspaceType) {
+ //this.dirName = path.dirname(dirName).split(path.sep).pop()!.toString();
+ // or path.basename(path.dirname(filename))
+ this.workspace = workspaceUri;
+ this.dirName = configPath !== '' ? path.basename(path.dirname(configPath)) : path.basename(workspaceUri.path);
+ this.configName = path.basename(configPath);
+ this.configPath = Uri.parse(configPath);
+ }
+
+ /**
+ * Represents the `basename`, _i.e._, the file name portion
+ */
+ readonly configName: string;
+
+ /**
+ * The last directory name where this config file is located.
+ */
+ readonly dirName: string;
+
+ /**
+ * The `Uri` root of the workspace or where hte config resides. Usually the same.
+ */
+ readonly workspace: Uri;
+
+ /**
+ * The full `Uri` path where this config file is located.
+ */
+ readonly configPath: Uri;
+}
+
+/**
+ * Using all the resolvers, resolve the projects/config files present in the workspaces.
+ */
+export function resolveAllWorkspaces(includeUnknown = true): AbstractWorkspace[] {
+ if (workspace.workspaceFolders === undefined) {
+ return [];
+ }
+ return workspace.workspaceFolders.flatMap((ws) => {
+ const foundWs = findWorkspaces(ws.uri.fsPath);
+ // patch in the unknown ones.
+ if (includeUnknown && foundWs?.length === 0) {
+ foundWs.push(AbstractWorkspace.createUnknownWorkspace(ws.uri));
+ }
+ return foundWs;
+ });
+}
+
+export const findWorkspaces = (workspaceRootPath: string): AbstractWorkspace[] => {
+ return WorkspaceResolvers.flatMap((r) =>
+ glob
+ .sync(`${workspaceRootPath}/**/${r.glob}`, {
+ ignore: Constants.workspaceIgnoredFolders,
+ })
+ .map((f) => AbstractWorkspace.createWorkspaceFromConfigPath(f, r.type))
+ );
+};
+
+/**
+ * Shows the list of `workspaces` in a quick pick so the user can select
+ * the correct config file to use.
+ *
+ * @param workspaces list of workspace folders to display to the user.
+ * @returns the config file of the selected Workspace.
+ */
+export async function selectConfigFromQuickPick(workspaces: AbstractWorkspace[]): Promise {
+ const folders = workspaces.map((element) => {
+ return {
+ label: element.dirName,
+ description: `Type: ${element.workspaceType} : ${element.configName}`,
+ detail: process.platform === 'win32' ? element.dirName : element.workspace.fsPath,
+ workspace: element,
+ };
+ });
+
+ const result = await showQuickPick(folders, {
+ ignoreFocusOut: true,
+ placeHolder: `Select a config file to use`,
+ });
+ return result.workspace;
+}
+
+export async function getWorkspaceForUri(contractUri?: Uri): Promise {
+ const workspaces = contractUri
+ ? findWorkspaces(workspace.getWorkspaceFolder(contractUri)!.uri.fsPath)
+ : resolveAllWorkspaces();
+ if (workspaces.length === 0) {
+ const error = new Error(Constants.errorMessageStrings.VariableShouldBeDefined('Workspace root'));
+ Telemetry.sendException(error);
+ throw error;
+ }
+
+ if (workspaces.length === 1) {
+ return workspaces[0];
+ }
+
+ return await selectConfigFromQuickPick(workspaces);
+}
diff --git a/src/helpers/TruffleConfiguration.ts b/src/helpers/TruffleConfiguration.ts
index fe84ffb3..9fd87e1d 100644
--- a/src/helpers/TruffleConfiguration.ts
+++ b/src/helpers/TruffleConfiguration.ts
@@ -13,7 +13,7 @@ import path from 'path';
import {Uri} from 'vscode';
import {ICommandResult, tryExecuteCommandInFork} from './command';
import {IConfiguration, INetwork, INetworkOption, IProvider, notAllowedSymbols} from './ConfigurationReader';
-import {getPathByPlatform, getWorkspaceRoot} from './workspace';
+import {getPathByPlatform, getWorkspaceRoot} from './WorkspaceHelpers';
export class EvalTruffleConfigError extends Error {
constructor(message: string, readonly reason: string) {
diff --git a/src/helpers/WorkspaceHelpers.ts b/src/helpers/WorkspaceHelpers.ts
new file mode 100644
index 00000000..f9aac1f2
--- /dev/null
+++ b/src/helpers/WorkspaceHelpers.ts
@@ -0,0 +1,64 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+import {TruffleCommands} from '@/commands';
+import {Constants} from '@/Constants';
+import {Telemetry} from '@/TelemetryClient';
+import * as path from 'path';
+import {Memento, TextDocument, Uri, workspace, WorkspaceFolder} from 'vscode';
+
+/**
+ * ! We need to remove this because it does not support multiple Truffle config files.
+ * @param ignoreException
+ * @returns
+ */
+export function getWorkspaceRoot(ignoreException = false): string | undefined {
+ const workspaceRoot =
+ workspace.workspaceFolders &&
+ (workspace.workspaceFolders.length === 0 ? undefined : workspace.workspaceFolders[0].uri.fsPath);
+
+ if (workspaceRoot === undefined && !ignoreException) {
+ const error = new Error(Constants.errorMessageStrings.VariableShouldBeDefined('Workspace root'));
+ Telemetry.sendException(error);
+ throw error;
+ }
+
+ return workspaceRoot;
+}
+
+/**
+ * Method to map filepaths properly on windows machines.
+ * @param workspace
+ */
+export const getPathByPlatform = (workspace: Uri): string =>
+ process.platform === 'win32' ? `${workspace.scheme}:${workspace.path}` : workspace.fsPath;
+
+/**
+ * Every time the `workspace.onDidSaveTextDocument` listener emits a notification,
+ * this function receives, identifies the file extension and calls the corresponding function.
+ *
+ * @param globalState A memento object that stores state independent of the current opened workspace.
+ * @param document Represents a text document, such as a source file.
+ */
+export async function saveTextDocument(globalState: Memento, document: TextDocument): Promise {
+ switch (path.extname(document.fileName)) {
+ case '.sol': {
+ // Gets the current state of the status bar item
+ const isAutoDeployOnSaveEnabled = globalState.get(Constants.globalStateKeys.contractAutoDeployOnSave);
+
+ // If enabled, calls the function that performs the deployment
+ if (isAutoDeployOnSaveEnabled) {
+ await TruffleCommands.deployContracts(Uri.parse(document.fileName));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * Gets the first Workspace folder or undefined.
+ */
+export const getWorkspaceFolder = (): WorkspaceFolder | undefined =>
+ workspace.workspaceFolders?.filter((folder) => folder.uri.scheme === 'file')[0];
diff --git a/src/helpers/command.ts b/src/helpers/command.ts
index 97e6e1c4..228ac62f 100644
--- a/src/helpers/command.ts
+++ b/src/helpers/command.ts
@@ -31,7 +31,7 @@ export interface ICommandExecute {
export async function executeCommand(
workingDirectory: string | undefined,
- commands: string,
+ command: string,
...args: string[]
): Promise {
Output.outputLine(
@@ -39,47 +39,46 @@ export async function executeCommand(
'\n' +
`Working dir: ${workingDirectory}\n` +
`${Constants.executeCommandMessage.runningCommand}\n` +
- `${[commands, ...args].join(' ')}`
+ `${[command, ...args].join(' ')}`
);
Telemetry.sendEvent('command.executeCommand.tryExecuteCommandWasStarted');
- const result: ICommandResult = await tryExecuteCommand(workingDirectory, commands, ...args);
+ const result: ICommandResult = await tryExecuteCommand(workingDirectory, command, ...args);
Output.outputLine(OutputLabel.executeCommand, Constants.executeCommandMessage.finishRunningCommand);
if (result.code !== 0) {
Telemetry.sendException(new Error('commands.executeCommand.resultWithIncorrectCode'));
- throw new Error(Constants.executeCommandMessage.failedToRunCommand(commands.concat(' ', ...args.join(' '))));
+ throw new Error(Constants.executeCommandMessage.failedToRunCommand(command.concat(' ', ...args.join(' '))));
}
return result.cmdOutput;
}
-export function spawnProcess(workingDirectory: string | undefined, commands: string, args: string[]): ChildProcess {
+export function spawnProcess(workingDirectory: string | undefined, command: string, args: string[]): ChildProcess {
const options: SpawnOptions = {cwd: workingDirectory || tmpdir(), shell: true};
- return spawn(commands, args, options);
+ return spawn(command, args, options);
}
export async function tryExecuteCommand(
workingDirectory: string | undefined,
- commands: string,
+ command: string,
...args: string[]
): Promise {
- const {result} = await tryExecuteCommandAsync(workingDirectory, true, commands, ...args);
-
+ const {result} = await tryExecuteCommandAsync(workingDirectory, true, command, ...args);
return result;
}
export async function tryExecuteCommandAsync(
workingDirectory: string | undefined,
writeToOutputChannel: boolean,
- commands: string,
+ command: string,
...args: string[]
): Promise {
let cmdOutput = '';
let cmdOutputIncludingStderr = '';
- const childProcess = spawnProcess(workingDirectory, commands, args);
+ const childProcess = spawnProcess(workingDirectory, command, args);
const result = new Promise((resolve: (res: any) => void, reject: (error: Error) => void): void => {
childProcess.stdout!.on('data', (data: string | Buffer) => {
data = data.toString();
diff --git a/src/helpers/required.ts b/src/helpers/required.ts
index fc3495aa..3d1ee035 100644
--- a/src/helpers/required.ts
+++ b/src/helpers/required.ts
@@ -5,9 +5,9 @@ import {getTruffleConfigUri, TruffleConfig} from '@/helpers/TruffleConfiguration
import fs from 'fs-extra';
import path from 'path';
import semver from 'semver';
-import {commands, ProgressLocation, window} from 'vscode';
-import {Constants, RequiredApps} from '@/Constants';
-import {getWorkspaceRoot} from '@/helpers/workspace';
+import {commands, ProgressLocation, Uri, window} from 'vscode';
+import {Constants, RequiredApps, OptionalApps, AppTypes} from '@/Constants';
+import {getPathByPlatform, getWorkspaceFolder, getWorkspaceRoot} from '@/helpers/WorkspaceHelpers';
import {Output, OutputLabel} from '@/Output';
import {Telemetry} from '@/TelemetryClient';
import {executeCommand, tryExecuteCommand} from './command';
@@ -25,6 +25,8 @@ export namespace required {
global = 0,
}
+ type VersionCallback = () => Promise;
+
const currentState: {[key: string]: IRequiredVersion} = {};
const requiredApps = [RequiredApps.node, RequiredApps.npm, RequiredApps.git];
@@ -83,10 +85,15 @@ export namespace required {
return valid;
}
- export async function checkAppsSilent(...apps: RequiredApps[]): Promise {
- const versions = await getExactlyVersions(...apps);
+ export async function checkAppsSilent(...apps: AppTypes[]): Promise {
+ const rootWorkspace = getWorkspaceFolder();
+ return checkAppsSilentForUri(rootWorkspace!.uri, ...apps);
+ }
+
+ export async function checkAppsSilentForUri(workspaceUri: Uri, ...apps: AppTypes[]): Promise {
+ const versions = await getExactlyVersions(workspaceUri, ...apps);
const invalid = versions
- .filter((version) => apps.includes(version.app as RequiredApps))
+ .filter((version) => apps.includes(version.app as AppTypes))
.some((version) => !version.isValid);
Output.outputLine(
@@ -152,10 +159,11 @@ export namespace required {
}
export async function getAllVersions(): Promise {
- return getExactlyVersions(...requiredApps, ...auxiliaryApps);
+ const rootWorkspace = getWorkspaceFolder();
+ return getExactlyVersions(rootWorkspace!.uri, ...requiredApps, ...auxiliaryApps);
}
- export async function getExactlyVersions(...apps: RequiredApps[]): Promise {
+ export async function getExactlyVersions(workspaceUri: Uri, ...apps: AppTypes[]): Promise {
Output.outputLine(OutputLabel.requirements, `Get version for required apps: ${apps.join(',')}`);
if (apps.includes(RequiredApps.node)) {
@@ -175,10 +183,31 @@ export namespace required {
currentState.ganache =
currentState.ganache || (await createRequiredVersion(RequiredApps.ganache, getGanacheVersion));
}
+ if (apps.includes(OptionalApps.hardhat)) {
+ currentState.hardhat =
+ currentState.hardhat ||
+ (await createRequiredVersion(OptionalApps.hardhat, getNpmPackageVersion(workspaceUri, OptionalApps.hardhat)));
+ }
return Object.values(currentState);
}
+ /**
+ * Run an NPM ls command to see if a specific package is installed within the NPM system in this project.
+ * @param workspaceUri - the uri of the workspace we want the npm package call to be run in.
+ * @param packageName - the npm specific name
+ */
+ const getNpmPackageVersion: (workspaceUri: Uri, packageName: string) => VersionCallback =
+ (workspaceUri: Uri, packageName: string) => async () => {
+ const platformPath = getPathByPlatform(workspaceUri);
+ return await getVersionWithArgs(
+ platformPath,
+ RequiredApps.npm,
+ ['ls', '--pareseable', '--long', '--depth=0', packageName],
+ new RegExp(`${packageName}@(\\d+.\\d+.\\d+)`)
+ );
+ };
+
export async function getNodeVersion(): Promise {
return await getVersion(RequiredApps.node, '--version', /v(\d+.\d+.\d+)/);
}
@@ -275,7 +304,7 @@ export namespace required {
return false;
}
- async function createRequiredVersion(appName: string, versionFunc: () => Promise): Promise {
+ async function createRequiredVersion(appName: string, versionFunc: VersionCallback): Promise {
const version = await versionFunc();
const requiredVersion = Constants.requiredVersions[appName];
const minRequiredVersion = typeof requiredVersion === 'string' ? requiredVersion : requiredVersion.min;
@@ -318,13 +347,21 @@ export namespace required {
}
async function getVersion(program: string, command: string, matcher: RegExp): Promise {
+ return getVersionWithArgs(undefined, program, [command], matcher);
+ }
+
+ async function getVersionWithArgs(
+ workingDirectory: string | undefined,
+ program: string,
+ commands: string[],
+ matcher: RegExp
+ ): Promise {
try {
- const result = await tryExecuteCommand(undefined, program, command);
+ const result = await tryExecuteCommand(workingDirectory, program, ...commands);
if (result.code === 0) {
const output = result.cmdOutput || result.cmdOutputIncludingStderr;
const installedVersion = output.match(matcher);
const version = semver.clean(installedVersion ? installedVersion[1] : '');
-
return version || '';
}
} catch (error) {
diff --git a/src/helpers/workspace.ts b/src/helpers/workspace.ts
index 04ddfa2d..286a7d10 100644
--- a/src/helpers/workspace.ts
+++ b/src/helpers/workspace.ts
@@ -1,18 +1,17 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
-import {Memento, TextDocument, Uri, workspace} from 'vscode';
import {Constants} from '@/Constants';
+import {showQuickPick} from '@/helpers/userInteraction';
import {Telemetry} from '@/TelemetryClient';
-import * as path from 'path';
import glob from 'glob';
-import {showQuickPick} from '@/helpers/userInteraction';
-import {TruffleCommands} from '@/commands';
+import * as path from 'path';
+import {Uri, workspace} from 'vscode';
/**
* The [glob](https://github.com/isaacs/node-glob#glob-primer) pattern to match Truffle config file names.
*/
-const TRUFFLE_CONFIG_GLOB = 'truffle-config{,.*}.js';
+const TRUFFLE_CONFIG_GLOB = 'truffle-config*.js';
/**
* A Truffle workspace is defined by the presence of a Truffle config file.
@@ -127,20 +126,11 @@ export function getPathByPlatform(workspace: Uri): string {
*
* @returns all Truffle config files found wrapped in {@link TruffleWorkspace}.
*/
-export async function getAllTruffleWorkspaces(): Promise {
+export function getAllTruffleWorkspaces(): TruffleWorkspace[] {
if (workspace.workspaceFolders === undefined) {
return [];
}
-
- const workspaces: TruffleWorkspace[] = [];
-
- await Promise.all(
- workspace.workspaceFolders.map(async (ws) => {
- workspaces.push(...(await findTruffleWorkspaces(ws.uri.fsPath)));
- })
- );
-
- return workspaces;
+ return workspace.workspaceFolders.flatMap((ws) => findTruffleWorkspaces(ws.uri.fsPath));
}
/**
@@ -154,11 +144,10 @@ export async function getAllTruffleWorkspaces(): Promise {
* @param workspaceRootPath the root path where to look for Truffle config files.
* @returns all Truffle config files found wrapped in `TruffleWorkspace`.
*/
-async function findTruffleWorkspaces(workspaceRootPath: string): Promise {
+function findTruffleWorkspaces(workspaceRootPath: string): TruffleWorkspace[] {
const files = glob.sync(`${workspaceRootPath}/**/${TRUFFLE_CONFIG_GLOB}`, {
ignore: Constants.workspaceIgnoredFolders,
});
-
return files.map((file) => new TruffleWorkspace(file));
}
@@ -186,25 +175,3 @@ async function selectTruffleConfigFromQuickPick(workspaces: TruffleWorkspace[]):
return result.truffleWorkspace;
}
-
-/**
- * Every time the `workspace.onDidSaveTextDocument` listener emits a notification,
- * this function receives, identifies the file extension and calls the corresponding function.
- *
- * @param globalState A memento object that stores state independent of the current opened workspace.
- * @param document Represents a text document, such as a source file.
- */
-export async function saveTextDocument(globalState: Memento, document: TextDocument): Promise {
- switch (path.extname(document.fileName)) {
- case '.sol': {
- // Gets the current state of the status bar item
- const isAutoDeployOnSaveEnabled = globalState.get(Constants.globalStateKeys.contractAutoDeployOnSave);
-
- // If enabled, calls the function that performs the deployment
- if (isAutoDeployOnSaveEnabled) await TruffleCommands.deployContracts(Uri.parse(document.fileName));
- break;
- }
- default:
- break;
- }
-}
diff --git a/src/services/contract/ContractService.ts b/src/services/contract/ContractService.ts
index 849b69bb..78e7d1fd 100644
--- a/src/services/contract/ContractService.ts
+++ b/src/services/contract/ContractService.ts
@@ -100,4 +100,19 @@ export namespace ContractService {
return path.join(workDir, dir);
}
+
+ // async function getPathDirectoryAW(directory: PathDirectoryKey, workspace?: AbstractWorkspace): Promise {
+ // const [workDir, name] = workspace
+ // ? [getPathByPlatform(workspace.workspace), workspace.configName]
+ // : [getWorkspaceRoot()!, undefined];
+ // const configuration = await getTruffleConfiguration(workDir, name);
+ //
+ // const dir = (configuration as any)[directory];
+ //
+ // if (dir && path.isAbsolute(dir)) {
+ // return dir;
+ // }
+ //
+ // return path.join(workDir, dir);
+ // }
}
diff --git a/src/services/extensionAdapter/HardHatExtensionAdapter.ts b/src/services/extensionAdapter/HardHatExtensionAdapter.ts
new file mode 100644
index 00000000..deddc825
--- /dev/null
+++ b/src/services/extensionAdapter/HardHatExtensionAdapter.ts
@@ -0,0 +1,29 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+import {buildContracts} from '@/commands/HardhatCommands';
+import {NotificationOptions} from '@/Constants';
+import {AbstractWorkspace, WorkspaceType} from '@/helpers/AbstractWorkspace';
+import {showNotification} from '@/helpers/userInteraction';
+import {IExtensionAdapter} from '@/services/extensionAdapter/IExtensionAdapter';
+import {Constants} from '@/constants';
+import {Uri} from 'vscode';
+
+export class HardHatExtensionAdapter implements IExtensionAdapter {
+ build(workspace: AbstractWorkspace, contractUri?: Uri): Promise {
+ return buildContracts(workspace, contractUri);
+ }
+
+ async deploy(_: AbstractWorkspace, _uri?: Uri): Promise {
+ await showNotification({
+ message: Constants.errorMessageStrings.HHNoDefaultDeploy,
+ type: NotificationOptions.error,
+ });
+ }
+
+ async validateExtension(): Promise {
+ return Promise.resolve(undefined);
+ }
+
+ extensionType: WorkspaceType = WorkspaceType.HARDHAT;
+}
diff --git a/src/services/extensionAdapter/IExtensionAdapter.ts b/src/services/extensionAdapter/IExtensionAdapter.ts
index 370fbb1e..8da10b14 100644
--- a/src/services/extensionAdapter/IExtensionAdapter.ts
+++ b/src/services/extensionAdapter/IExtensionAdapter.ts
@@ -1,10 +1,13 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
+
+import {AbstractWorkspace, WorkspaceType} from '@/helpers/AbstractWorkspace';
import {Uri} from 'vscode';
export interface IExtensionAdapter {
+ extensionType: WorkspaceType;
validateExtension: () => Promise;
- build: (contractUri?: Uri) => Promise;
- deploy: (contractUri?: Uri) => Promise;
+ build: (workspace: AbstractWorkspace, contractUri?: Uri) => Promise;
+ deploy: (workspace: AbstractWorkspace, contractUri?: Uri) => Promise;
}
diff --git a/src/services/extensionAdapter/TruffleExtensionAdapter.ts b/src/services/extensionAdapter/TruffleExtensionAdapter.ts
index 3a3d6791..0af13deb 100644
--- a/src/services/extensionAdapter/TruffleExtensionAdapter.ts
+++ b/src/services/extensionAdapter/TruffleExtensionAdapter.ts
@@ -1,8 +1,9 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
+import {TruffleCommands} from '@/commands';
+import {AbstractWorkspace, WorkspaceType} from '@/helpers/AbstractWorkspace';
import {Uri} from 'vscode';
-import {TruffleCommands} from '../../commands/TruffleCommands';
import {IExtensionAdapter} from './IExtensionAdapter';
export class TruffleExtensionAdapter implements IExtensionAdapter {
@@ -10,11 +11,13 @@ export class TruffleExtensionAdapter implements IExtensionAdapter {
// throw new Error("Method not implemented.");
};
- public build = async (uri?: Uri): Promise => {
- return TruffleCommands.buildContracts(uri);
+ public build = async (_: AbstractWorkspace, contractUri?: Uri): Promise => {
+ return TruffleCommands.buildContracts(contractUri);
};
- public deploy = async (uri?: Uri): Promise => {
- return TruffleCommands.deployContracts(uri);
+ public deploy = async (_: AbstractWorkspace): Promise => {
+ return TruffleCommands.deployContracts();
};
+
+ extensionType: WorkspaceType = WorkspaceType.TRUFFLE;
}
diff --git a/src/services/extensionAdapter/UnknownExtensionAdapter.ts b/src/services/extensionAdapter/UnknownExtensionAdapter.ts
new file mode 100644
index 00000000..2ca751d9
--- /dev/null
+++ b/src/services/extensionAdapter/UnknownExtensionAdapter.ts
@@ -0,0 +1,22 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+import {AbstractWorkspace, WorkspaceType} from '@/helpers/AbstractWorkspace';
+import {Uri} from 'vscode';
+import {IExtensionAdapter} from './IExtensionAdapter';
+
+export class UnknownExtensionAdapter implements IExtensionAdapter {
+ public validateExtension = async (): Promise => {
+ // throw new Error("Method not implemented.");
+ };
+
+ public build = async (_: AbstractWorkspace, __?: Uri): Promise => {
+ // TODO:throw some info here?
+ };
+
+ public deploy = async (_: AbstractWorkspace): Promise => {
+ // TODO:throw some info here?
+ };
+
+ extensionType: WorkspaceType = WorkspaceType.UNKNOWN;
+}
diff --git a/src/services/extensionAdapter/index.ts b/src/services/extensionAdapter/index.ts
index 8cccad5a..ec64d635 100644
--- a/src/services/extensionAdapter/index.ts
+++ b/src/services/extensionAdapter/index.ts
@@ -3,3 +3,5 @@
export * from './IExtensionAdapter';
export * from './TruffleExtensionAdapter';
+export * from './UnknownExtensionAdapter';
+export * from './HardHatExtensionAdapter';
diff --git a/src/views/DeploymentsView.ts b/src/views/DeploymentsView.ts
index 9401d3a1..32ab1398 100644
--- a/src/views/DeploymentsView.ts
+++ b/src/views/DeploymentsView.ts
@@ -14,7 +14,7 @@ import {
Command,
ThemeColor,
} from 'vscode';
-import {getChain, getExplorerLink} from '../functions/explorer';
+import {getChain, getExplorerLink} from '@/functions/explorer';
import {OpenUrlTreeItem} from './lib/OpenUrlTreeItem';
import {ContractService} from '@/services/contract/ContractService';
import {getAllTruffleWorkspaces, TruffleWorkspace} from '@/helpers/workspace';
@@ -300,7 +300,10 @@ class DeploymentsView implements TreeDataProvider {
return (element as TreeParentItem).loadChildren();
}
- const truffleWorkspaces = await getAllTruffleWorkspaces();
+ // TODO: just the truffle ones maam.
+ // const workspaces = resolveAllWorkspaces().filter((ws) => ws.workspaceType === WorkspaceType.TRUFFLE);
+
+ const truffleWorkspaces = getAllTruffleWorkspaces();
if (truffleWorkspaces.length === 0) {
return [];
} else if (truffleWorkspaces.length === 1) {
diff --git a/src/views/FileExplorer.ts b/src/views/FileExplorer.ts
index a9838222..9656a193 100644
--- a/src/views/FileExplorer.ts
+++ b/src/views/FileExplorer.ts
@@ -5,7 +5,7 @@ import * as path from 'path';
import * as rimraf from 'rimraf';
import * as vscode from 'vscode';
import {ThemeColor, ThemeIcon, Uri} from 'vscode';
-import {Constants} from '../Constants';
+import {Constants} from '@/Constants';
import {ContractService} from '@/services/contract/ContractService';
//#region Utilities
@@ -188,6 +188,26 @@ export type Entry = vscode.Uri & {
contextValue?: string;
};
+// /**
+// * Represents a top-level `TreeItem` for our file view...
+// *
+// * This gives us a few more free items in terms of customisation over the original view item.
+// */
+// class TreeItemEntry extends TreeItem {
+// constructor(
+// path: string,
+// uri: vscode.Uri,
+// public readonly type: FileType,
+// description?: string,
+// icon?: vscode.ThemeIcon
+// ) {
+// super(path);
+// this.resourceUri = uri;
+// if (icon) this.iconPath = icon;
+// if (description) this.description = description;
+// }
+// }
+
export type TElementTypes = {
contextValue: string;
type: vscode.FileType;
@@ -256,9 +276,7 @@ export class FileSystemProvider implements vscode.TreeDataProvider, vscod
{recursive: options.recursive},
async (event: string, filename: string | Buffer) => {
const filepath = path.join(uri.fsPath, _.normalizeNFC(filename.toString()));
-
// TODO support excludes (using minimatch library?)
-
this._onDidChangeFile.fire([
{
type:
@@ -364,7 +382,6 @@ export class FileSystemProvider implements vscode.TreeDataProvider, vscod
if (!parentExists) {
await _.mkdir(path.dirname(newUri.fsPath));
}
-
return _.rename(oldUri.fsPath, newUri.fsPath);
}
@@ -389,7 +406,8 @@ export class FileSystemProvider implements vscode.TreeDataProvider, vscod
const elements: Entry[] = [];
// Gets the truffle workspaces
- const workspaces = await getAllTruffleWorkspaces();
+ const workspaces = getAllTruffleWorkspaces();
+ console.log(`getChildren: `, {workspaces, element});
// Checks if there are any truffle workspaces
if (workspaces.length === 0) {
@@ -420,7 +438,7 @@ export class FileSystemProvider implements vscode.TreeDataProvider, vscod
type: vscode.FileType.Directory,
label: path.basename(contractFolder),
iconPath: new ThemeIcon('file-directory'),
- description: path.basename(path.dirname(contractFolder)),
+ description: `${path.basename(path.dirname(contractFolder))} - (${workspace.truffleConfigName})`,
contextValue: this.getTreeItemContextValue(vscode.FileType.Directory, true),
})
);
@@ -475,7 +493,7 @@ export class FileSystemProvider implements vscode.TreeDataProvider, vscod
}
/**
- * Gets the context value from element according on the type: root, folder, or file.
+ * Gets the context value from element according to the type: root, folder, or file.
* The `context Value` offers a filter on the file explorer menu that filters action alternatives such as:
* `Create Contract`, `Build Contracts`, `Build This Contract`, `Deploy Contracts` and `Debug Transaction`.
*
diff --git a/test/TruffleConfig.test.ts b/test/TruffleConfig.test.ts
index 9d946aef..5d9e64ca 100644
--- a/test/TruffleConfig.test.ts
+++ b/test/TruffleConfig.test.ts
@@ -7,7 +7,7 @@ import fs from 'fs-extra';
import path from 'path';
import sinon from 'sinon';
import {Constants} from '@/Constants';
-import * as helpers from '@/helpers/workspace';
+import * as helpers from '@/helpers/WorkspaceHelpers';
import * as commands from '../src/helpers/command';
import {ICommandResult} from '@/helpers/command';
import {getTruffleConfiguration, getTruffleConfigUri, TruffleConfig} from '@/helpers/TruffleConfiguration';
diff --git a/test/TruffleExtensionAdapter.test.ts b/test/TruffleExtensionAdapter.test.ts
index 8c7f0975..e141cd45 100644
--- a/test/TruffleExtensionAdapter.test.ts
+++ b/test/TruffleExtensionAdapter.test.ts
@@ -1,21 +1,24 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
+import * as AW from '@/helpers/AbstractWorkspace';
import assert from 'assert';
-import sinon from 'sinon';
-import {TruffleCommands} from '../src/commands/TruffleCommands';
-import {TruffleExtensionAdapter} from '../src/services/extensionAdapter';
+import sinon, {mock} from 'sinon';
+import {TruffleCommands} from '@/commands';
+import {TruffleExtensionAdapter} from '@/services/extensionAdapter';
describe('TruffleExtensionAdapter', () => {
let buildContractsMock: sinon.SinonStub;
let deployContractsMock: sinon.SinonStub;
let truffleExtensionAdapter: TruffleExtensionAdapter;
+ let workspaceMock: any;
beforeEach(() => {
buildContractsMock = sinon.stub(TruffleCommands, 'buildContracts');
deployContractsMock = sinon.stub(TruffleCommands, 'deployContracts');
truffleExtensionAdapter = new TruffleExtensionAdapter();
+ workspaceMock = mock(AW.AbstractWorkspace);
});
afterEach(() => {
@@ -24,15 +27,15 @@ describe('TruffleExtensionAdapter', () => {
it('build method should call truffleCommands.buildContracts', async () => {
// Act
- await truffleExtensionAdapter.build();
+ await truffleExtensionAdapter.build(workspaceMock);
// Assert
assert.strictEqual(buildContractsMock.calledOnce, true, 'TruffleCommands.buildContracts should be called once');
});
- it('deploy method should call truffleCommands.buildContracts', async () => {
+ it('deploy method should call truffleCommands.deployContracts', async () => {
// Act
- await truffleExtensionAdapter.deploy();
+ await truffleExtensionAdapter.deploy(workspaceMock);
// Assert
assert.strictEqual(deployContractsMock.calledOnce, true, 'TruffleCommands.deployContracts should be called once');
diff --git a/test/commands/DebuggerCommands.test.ts b/test/commands/DebuggerCommands.test.ts
index e12d82d8..df2c9ba6 100644
--- a/test/commands/DebuggerCommands.test.ts
+++ b/test/commands/DebuggerCommands.test.ts
@@ -1,30 +1,32 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
+import {DebugNetwork} from '@/debugAdapter/debugNetwork';
+import {ITransactionResponse} from '@/debugAdapter/models/ITransactionResponse';
+import {TransactionProvider} from '@/debugAdapter/transaction/transactionProvider';
+import {AbstractWorkspace, WorkspaceType} from '@/helpers/AbstractWorkspace';
+
+import * as aw from '@/helpers/AbstractWorkspace';
import assert from 'assert';
import path from 'path';
import sinon from 'sinon';
import {debug, QuickPickItem, Uri, workspace} from 'vscode';
-import {DebugNetwork} from '@/debugAdapter/debugNetwork';
-import {ITransactionResponse} from '@/debugAdapter/models/ITransactionResponse';
-import {TransactionProvider} from '@/debugAdapter/transaction/transactionProvider';
-
import * as userInteraction from '../../src/helpers/userInteraction';
import {TestConstants} from '../TestConstants';
-import * as helpers from '@/helpers/workspace';
import {shortenHash} from '@/commands/DebuggerCommands';
-const truffleWorkspace = new helpers.TruffleWorkspace(
- path.join(__dirname, TestConstants.truffleCommandTestDataFolder, 'truffle-config.js')
+const truffleWorkspace = AbstractWorkspace.createWorkspaceFromConfigPath(
+ path.join(__dirname, TestConstants.truffleCommandTestDataFolder, 'truffle-config.js'),
+ WorkspaceType.TRUFFLE
);
describe('DebuggerCommands mock tests', () => {
let mockGetTxHashes: sinon.SinonStub<[(number | undefined)?], Promise>;
let mockGetTxInfos: sinon.SinonStub<[string[]], Promise>;
let debugCommands: any;
- let getWorkspacesMock: sinon.SinonStub<[contractUri?: Uri], Promise>;
+ let getWorkspacesMock: sinon.SinonStub<[contractUri?: Uri], Promise>;
beforeEach(() => {
mockGetTxHashes = sinon.stub(TransactionProvider.prototype, 'getLastTransactionHashes');
@@ -32,7 +34,7 @@ describe('DebuggerCommands mock tests', () => {
mockGetTxInfos = sinon.stub(TransactionProvider.prototype, 'getTransactionsInfo');
mockGetTxInfos.resolves([]);
- getWorkspacesMock = sinon.stub(helpers, 'getTruffleWorkspace');
+ getWorkspacesMock = sinon.stub(aw, 'getWorkspaceForUri');
getWorkspacesMock.returns(Promise.resolve(truffleWorkspace));
sinon.stub(debug, 'startDebugging').resolves();
diff --git a/test/commands/GanacheCommands.int.test.ts b/test/commands/GanacheCommands.int.test.ts
index 5c7630bf..38832fd4 100644
--- a/test/commands/GanacheCommands.int.test.ts
+++ b/test/commands/GanacheCommands.int.test.ts
@@ -1,18 +1,18 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
+import {GanacheCommands} from '@/commands';
+import {IExtensionItem, LocalProject, LocalService, Service, TLocalProjectOptions} from '@/Models/TreeItems';
+import {TreeManager} from '@/services';
+import {ProjectView} from '@/ViewItems';
import assert from 'assert';
import cp, {ChildProcess} from 'child_process';
import rp from 'request-promise';
import sinon from 'sinon';
import stream from 'stream';
import * as vscode from 'vscode';
-import {GanacheCommands} from '../../src/commands';
import * as commands from '../../src/helpers/command';
import * as shell from '../../src/helpers/shell';
-import {IExtensionItem, LocalProject, LocalService, Service, TLocalProjectOptions} from '../../src/Models/TreeItems';
-import {TreeManager} from '../../src/services';
-import {ProjectView} from '../../src/ViewItems';
describe('Integration tests GanacheCommands', () => {
const defaultPort = 8545;
@@ -20,6 +20,7 @@ describe('Integration tests GanacheCommands', () => {
let serviceItems: Service[];
let loadStateMock: sinon.SinonStub<[], IExtensionItem[]>;
let projectView: ProjectView;
+ let workspaceMock: any;
const description = '';
@@ -57,6 +58,15 @@ describe('Integration tests GanacheCommands', () => {
getItemsMock.returns(serviceItems);
loadStateMock = sinon.stub(TreeManager, 'loadState');
loadStateMock.returns(serviceItems);
+ // is this enough?
+ workspaceMock = sinon.stub(vscode.workspace, 'workspaceFolders');
+ workspaceMock.value([
+ {
+ uri: vscode.Uri.file('testy'),
+ index: 0,
+ name: 'name',
+ },
+ ]);
projectView = new ProjectView(new LocalProject('test consortium', defaultPort, options, description));
@@ -65,6 +75,7 @@ describe('Integration tests GanacheCommands', () => {
});
afterEach(() => {
+ // workspaceMock.restore();
sinon.restore();
});
diff --git a/test/commands/GanacheCommands.test.ts b/test/commands/GanacheCommands.test.ts
index 152248b7..f26e49dc 100644
--- a/test/commands/GanacheCommands.test.ts
+++ b/test/commands/GanacheCommands.test.ts
@@ -5,15 +5,15 @@ import assert from 'assert';
import {ChildProcess} from 'child_process';
import sinon from 'sinon';
import {commands, OutputChannel, QuickPickItem, window} from 'vscode';
-import {GanacheCommands} from '../../src/commands';
-import {Constants, RequiredApps} from '../../src/Constants';
+import {GanacheCommands} from '@/commands';
+import {Constants, RequiredApps} from '@/Constants';
import * as userInteraction from '../../src/helpers/userInteraction';
-import {required} from '../../src/helpers/required';
+import {required} from '@/helpers/required';
import * as shell from '../../src/helpers/shell';
-import {IExtensionItem, LocalProject, LocalService, Service, TLocalProjectOptions} from '../../src/Models/TreeItems';
-import {GanacheService, TreeManager} from '../../src/services';
+import {IExtensionItem, LocalProject, LocalService, Service, TLocalProjectOptions} from '@/Models/TreeItems';
+import {GanacheService, TreeManager} from '@/services';
import * as GanacheServiceClient from '../../src/services/ganache/GanacheServiceClient';
-import {ProjectView} from '../../src/ViewItems';
+import {ProjectView} from '@/ViewItems';
import {TestConstants} from '../TestConstants';
const description = '';
diff --git a/test/commands/ProjectCommand.test.ts b/test/commands/ProjectCommand.test.ts
index 398148db..fb6540d2 100644
--- a/test/commands/ProjectCommand.test.ts
+++ b/test/commands/ProjectCommand.test.ts
@@ -6,12 +6,12 @@ import fs from 'fs-extra';
import rewire from 'rewire';
import sinon from 'sinon';
import {CancellationToken, Progress, ProgressOptions, window, workspace} from 'vscode';
-import {Constants, RequiredApps} from '../../src/Constants';
+import {Constants, RequiredApps} from '@/Constants';
import * as helpers from '../../src/helpers/';
-import {required} from '../../src/helpers/required';
+import {required} from '@/helpers/required';
import * as userInteraction from '../../src/helpers/userInteraction';
-import {CancellationEvent} from '../../src/Models';
-import {Output} from '../../src/Output';
+import {CancellationEvent} from '@/Models';
+import {Output} from '@/Output';
import * as vscode from 'vscode';
enum ProjectType {
diff --git a/test/commands/SdkCoreCommands.test.ts b/test/commands/SdkCoreCommands.test.ts
new file mode 100644
index 00000000..dd87b98f
--- /dev/null
+++ b/test/commands/SdkCoreCommands.test.ts
@@ -0,0 +1,124 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+import * as AW from '@/helpers/AbstractWorkspace';
+import {expect} from 'chai';
+import glob from 'glob';
+import fs from 'fs';
+import sinon from 'sinon';
+import {sdkCoreCommands} from '@/commands/SdkCoreCommands';
+import {Uri, workspace, WorkspaceFolder} from 'vscode';
+import {TruffleCommands} from '@/commands/TruffleCommands';
+import * as HardhatCommands from '@/commands/HardhatCommands';
+
+describe('SDK Core Commands', () => {
+ const sandbox = sinon.createSandbox();
+
+ let globStub: any;
+ let fsStub: any;
+ let truffleBuildStub: any;
+ let hardhatBuildStub: any;
+ let workspaces: WorkspaceFolder[] = [];
+
+ const setupTestScenario = function (testFolderName: string, globPattern: any) {
+ const foundFile = testFolderName + '/someconfig.file';
+ workspaces.push({
+ uri: Uri.file(testFolderName),
+ index: 0,
+ name: testFolderName + '-name',
+ });
+ // just return a truffle one... we only want to return 1
+ globStub.withArgs().callsFake(function (pattern: string): string[] {
+ return pattern.includes(globPattern) ? [foundFile] : [];
+ });
+ };
+
+ let extensionAdapterSpy: any;
+
+ beforeEach(async () => {
+ //setup the mockery...
+ const getWorkspsaceFolderStub = sandbox.stub(workspace, 'getWorkspaceFolder');
+ getWorkspsaceFolderStub.callsFake((_uri) => workspaces[0]);
+
+ const workspaceFolders = sandbox.stub(workspace, 'workspaceFolders');
+ workspaceFolders.value(workspaces);
+
+ truffleBuildStub = sandbox.stub(TruffleCommands, 'buildContracts');
+ truffleBuildStub.returns();
+
+ hardhatBuildStub = sandbox.stub(HardhatCommands, 'buildContracts');
+ hardhatBuildStub.returns();
+
+ fsStub = sandbox.stub(fs, 'lstatSync');
+ fsStub.returns({
+ isFile() {
+ return true;
+ },
+ });
+
+ globStub = sandbox.stub(glob, 'sync');
+ extensionAdapterSpy = sandbox.spy(sdkCoreCommands, 'getExtensionAdapter');
+ });
+
+ afterEach(async () => {
+ workspaces = [];
+ sandbox.restore();
+ });
+
+ describe('SDK Commands - Project Resolution', () => {
+ it('will find correct command to build - truffle', async function () {
+ // given - truffle workspace
+ const wsFolder = 'truffle-project-1';
+ const buildFolder = Uri.file(wsFolder);
+ setupTestScenario(wsFolder, AW.TRUFFLE_CONFIG_GLOB);
+
+ // when I call build
+ await sdkCoreCommands.build(buildFolder);
+
+ // then the correct methods should have been called.
+ expect(extensionAdapterSpy.calledOnceWith(AW.WorkspaceType.TRUFFLE)).to.be.true;
+ expect(hardhatBuildStub.notCalled).to.be.true;
+ expect(truffleBuildStub.calledOnce).to.be.true;
+ // console.log(`args: `, {args: truffleBuildStub.firstCall.args}); // WORKSPACE args[0]
+ expect(truffleBuildStub.firstCall.args[0].path).to.be.eq('/truffle-project-1');
+ });
+
+ it('will find correct command to build - hardhat', async function () {
+ // given - hardhat workspace
+ const wsFolder = 'hardhat-project-1';
+ const buildFolder = Uri.file(wsFolder);
+ setupTestScenario(wsFolder, AW.HARDHAT_CONFIG_GLOB);
+
+ // when I call build
+ await sdkCoreCommands.build(buildFolder);
+
+ // then the correct methods should have been called.
+ expect(extensionAdapterSpy.calledOnceWith(AW.WorkspaceType.HARDHAT)).to.be.true;
+ expect(truffleBuildStub.notCalled).to.be.true;
+ expect(hardhatBuildStub.calledOnce).to.be.true;
+ // console.log(`args: `, {args: hardhatBuildStub.firstCall.args}); // WORKSPACE args[0]
+ expect(hardhatBuildStub.firstCall.args[1].path).to.be.eq('/hardhat-project-1');
+ });
+
+ it('will find correct command to build - unknown', async function () {
+ const wsFolder = 'some-empty-folder';
+ const buildFolder = Uri.file(wsFolder);
+ workspaces.push({
+ uri: buildFolder,
+ index: 0,
+ name: wsFolder + '-name',
+ });
+ // return 0 workspaces with actual configs in them.
+ globStub.withArgs().returns([]);
+
+ // when I call build - with no contract and ultimately no configured framework workspace...
+ await sdkCoreCommands.build();
+
+ // test the unknown one was also triggered...
+ expect(extensionAdapterSpy.calledOnceWith(AW.WorkspaceType.UNKNOWN)).to.be.true;
+ // then unknown will be called. not the others.
+ expect(truffleBuildStub.notCalled).to.be.true;
+ expect(hardhatBuildStub.notCalled).to.be.true;
+ });
+ });
+});
diff --git a/test/debugAdapter/debugSession.test.ts b/test/debugAdapter/debugSession.test.ts
index ff941dcc..e49f1d74 100644
--- a/test/debugAdapter/debugSession.test.ts
+++ b/test/debugAdapter/debugSession.test.ts
@@ -7,10 +7,10 @@ import {join as pathJoin} from 'path';
import sinon from 'sinon';
import {StoppedEvent} from '@vscode/debugadapter';
import {DebugProtocol} from '@vscode/debugprotocol';
-import {GET_CURRENT_INSTRUCTION, GET_INSTRUCTIONS} from '../../src/debugAdapter/constants/debugSessionCommands';
-import {SolidityDebugSession} from '../../src/debugAdapter/debugSession';
-import {DebuggerTypes} from '../../src/debugAdapter/models/debuggerTypes';
-import {IInstruction} from '../../src/debugAdapter/models/IInstruction';
+import {GET_CURRENT_INSTRUCTION, GET_INSTRUCTIONS} from '@/debugAdapter/constants/debugSessionCommands';
+import {SolidityDebugSession} from '@/debugAdapter/debugSession';
+import {DebuggerTypes} from '@/debugAdapter/models/debuggerTypes';
+import {IInstruction} from '@/debugAdapter/models/IInstruction';
import RuntimeInterface from '../../src/debugAdapter/runtimeInterface';
import {SolidityDebugSessionClient} from './SolidityDebugSessionClient';
@@ -22,7 +22,7 @@ describe('DebugSession unit tests', () => {
it("shouldn't contain vscode module as a dependency", (done) => {
// vscode module can be resolved inside of the extension without any issues
// that's why we should spawn independent node process to check
- const debugSessionModule = pathJoin(__dirname, '../../src/debugAdapter/debugSession.js');
+ const debugSessionModule = pathJoin(__dirname, '../../src/debugAdapter/debugSession.ts');
const debugSessionResolvingProcess = spawn(process.execPath, [debugSessionModule]);
debugSessionResolvingProcess.on('close', () => {
done();
diff --git a/test/mocks/MockExtensionContext.ts b/test/mocks/MockExtensionContext.ts
new file mode 100644
index 00000000..0ce4f43f
--- /dev/null
+++ b/test/mocks/MockExtensionContext.ts
@@ -0,0 +1,20 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+import {Disposable, ExtensionContext} from 'vscode';
+
+type ExtensionContextPlus = ExtensionContext & Pick;
+
+export class MockExtensionContext implements Partial {
+ subscriptions: Disposable[] = [];
+
+ asAbsolutePath = (relativePath: string): string => relativePath;
+
+ static new(): ExtensionContextPlus {
+ return new this() as unknown as ExtensionContextPlus;
+ }
+
+ teardown() {
+ this.subscriptions.forEach((x) => x.dispose());
+ }
+}
diff --git a/test/mocks/MockMemento.ts b/test/mocks/MockMemento.ts
new file mode 100644
index 00000000..54caebaf
--- /dev/null
+++ b/test/mocks/MockMemento.ts
@@ -0,0 +1,31 @@
+// Copyright (c) 2022. Consensys Software Inc. All rights reserved.
+// Licensed under the MIT license.
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable no-prototype-builtins */
+import {Memento} from 'vscode';
+
+export class MockMemento implements Memento {
+ constructor(private dict: {[id: string]: any} = {}) {}
+
+ // // _value must be named this way in order to match vscode's memento
+ // private _value: Record = {};
+
+ public get(key: any, defaultValue?: any): any;
+ public get(key: string, defaultValue?: T): T {
+ const exists = this.dict.hasOwnProperty(key);
+ return exists ? this.dict[key] : (defaultValue! as any);
+ }
+
+ public update(key: string, value: any): Thenable {
+ this.dict[key] = value;
+ return Promise.resolve();
+ }
+ public clear() {
+ this.dict = {};
+ }
+
+ keys(): readonly string[] {
+ return Object.keys(this.dict);
+ }
+}
diff --git a/test/required.test.ts b/test/required.test.ts
index 9a17f278..0225a2e1 100644
--- a/test/required.test.ts
+++ b/test/required.test.ts
@@ -6,9 +6,10 @@ import rewire from 'rewire';
import sinon from 'sinon';
import uuid from 'uuid';
import * as vscode from 'vscode';
-import {RequiredApps} from '../src/Constants';
-import * as helpers from '@/helpers/workspace';
-import * as commands from '../src/helpers/command';
+//import * as vscode from './vscode';
+import {RequiredApps} from '@/Constants';
+import * as helpers from '@/helpers/WorkspaceHelpers';
+import * as commands from '@/helpers/command';
import {TestConstants} from './TestConstants';
const nodeValidVersion: commands.ICommandResult = {
@@ -47,6 +48,19 @@ describe('Required helper', () => {
let executeCommandMock: any;
beforeEach(() => {
+ const workspaces = [
+ {
+ uri: vscode.Uri.file('testiy'),
+ index: 0,
+ name: 'name',
+ },
+ ];
+ const getWorkspsaceFolderStub = sinon.stub(vscode.workspace, 'getWorkspaceFolder');
+ getWorkspsaceFolderStub.callsFake((_uri) => workspaces[0]);
+
+ const workspaceFolders = sinon.stub(vscode.workspace, 'workspaceFolders');
+ workspaceFolders.value(workspaces);
+
requiredRewire = rewire('../src/helpers/required');
tryExecuteCommandMock = sinon.stub(commands, 'tryExecuteCommand');
getWorkspaceRootMock = sinon.stub(helpers, 'getWorkspaceRoot');
diff --git a/test/vscode.ts b/test/vscode.ts
index 354a1da3..b362c122 100644
--- a/test/vscode.ts
+++ b/test/vscode.ts
@@ -147,7 +147,7 @@ export const workspace = {
} as any;
},
- getWorkspaceFolder: function (_uri: Uri): WorkspaceFolder | undefined {
+ getWorkspaceFolder(_uri: Uri): WorkspaceFolder | undefined {
return workspace.workspaceFolders![0];
},
diff --git a/test/workspace.test.ts b/test/workspace.test.ts
index 94862491..b5b162ed 100644
--- a/test/workspace.test.ts
+++ b/test/workspace.test.ts
@@ -1,101 +1,230 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.
-import assert from 'assert';
+import * as AW from '@/helpers/AbstractWorkspace';
+import {AbstractWorkspace, resolveAllWorkspaces, WorkspaceType} from '@/helpers/AbstractWorkspace';
+import * as userInteraction from '@/helpers/userInteraction';
+import chai from 'chai';
+import chai_as_promised from 'chai-as-promised';
+import fs from 'fs';
+import glob from 'glob';
import sinon from 'sinon';
-import * as vscode from 'vscode';
-import {getTruffleWorkspace, getWorkspaceRoot} from '@/helpers/workspace';
-
-describe('workspace', () => {
- const testWorkspaceFolder: any[] = [
- {
- uri: {
- fsPath: 'testPath1',
- },
- },
- {
- uri: {
- fsPath: 'testPath2',
+import {QuickPickItem, Uri, workspace, WorkspaceFolder} from 'vscode';
+
+chai.use(chai_as_promised);
+const expect = chai.expect;
+
+type QuickPickType = {workspace: AbstractWorkspace; description: string; label: string; detail: string};
+
+describe('Workspace - WorkspaceForUri Tests', () => {
+ const sandbox = sinon.createSandbox();
+
+ let globStub: sinon.SinonStub;
+ let fsStub: sinon.SinonStub;
+ let quickPickStub: sinon.SinonStub>;
+
+ let workspaces: WorkspaceFolder[] = [];
+
+ const pushWorkspace = (testFolderName: string) =>
+ workspaces.push({
+ uri: Uri.file(testFolderName),
+ index: workspace.workspaceFolders ? workspace.workspaceFolders!.length : 0,
+ name: testFolderName + '-name',
+ });
+
+ const aw1 = AW.AbstractWorkspace.createUnknownWorkspace(Uri.file('/dev/unknown-aw1'));
+ const aw2 = AW.AbstractWorkspace.createWorkspaceFromConfigPath(
+ '/dev/truffle-aw2/bleh2.conf.js',
+ WorkspaceType.TRUFFLE
+ );
+
+ beforeEach(async () => {
+ //setup the mockery...
+ const getWorkspsaceFolderStub = sandbox.stub(workspace, 'getWorkspaceFolder');
+ getWorkspsaceFolderStub.callsFake((_uri) => workspaces[0]);
+
+ const workspaceFolders = sandbox.stub(workspace, 'workspaceFolders');
+ workspaceFolders.value(workspaces);
+
+ quickPickStub = sandbox.stub(userInteraction, 'showQuickPick');
+ fsStub = sandbox.stub(fs, 'lstatSync');
+ fsStub.returns({
+ isFile() {
+ return true;
},
- },
- ];
+ });
- let workspaceMock: sinon.SinonStub;
+ globStub = sandbox.stub(glob, 'sync');
+ globStub.withArgs().returns([]);
+ });
- beforeEach(() => {
- workspaceMock = sinon.stub(vscode.workspace, 'workspaceFolders');
+ afterEach(async () => {
+ sandbox.restore();
+ workspaces = [];
});
- afterEach(() => {
- workspaceMock.restore();
+ const setupTestScenario = function (testFolderName: string, globPattern: any) {
+ const foundFile = testFolderName + '/someconfig.file';
+ pushWorkspace(testFolderName);
+ // just return a matching one... we only want to return 1
+ globStub.withArgs().callsFake(function (pattern: string): string[] {
+ return pattern.includes(globPattern) ? [foundFile] : [];
+ });
+ };
+
+ it('will resolve workspace correctly - in a truffle folder.', async function () {
+ //given - I have the default value set.
+ const wsFolder = '/dev/some/thing/truffle-test';
+ setupTestScenario(wsFolder, AW.TRUFFLE_CONFIG_GLOB);
+
+ // when I call
+ const workspaceRet = await AW.getWorkspaceForUri(Uri.file(wsFolder));
+ // then the workspace will be correct
+ expect(workspaceRet.dirName).to.be.eq('truffle-test');
+ expect(workspaceRet.workspaceType).to.be.eq(AW.WorkspaceType.TRUFFLE);
});
- describe('getWorkspaceRoot', () => {
- it('should throw exception when no workspace is opened', () => {
- // Arrange
- workspaceMock.value(undefined);
+ it('will resolve workspace correctly - in a hardhat folder.', async function () {
+ //given - I have the default value set.
+ const wsFolder = '/dev/blah/blah/hardhat-test';
+ setupTestScenario(wsFolder, AW.HARDHAT_CONFIG_GLOB);
- // Act and assert
- assert.throws(getWorkspaceRoot, /Workspace root should be defined/);
- });
+ // when I call the workspace resolver...
+ const workspaceRet = await AW.getWorkspaceForUri(Uri.file(wsFolder));
- it('should throw exception when workspace is empty', () => {
- // Arrange
- workspaceMock.value([]);
+ // then the Truffle Instances will be called.
+ expect(workspaceRet.dirName).to.be.eq('hardhat-test');
+ expect(workspaceRet.workspaceType).to.be.eq(AW.WorkspaceType.HARDHAT);
+ });
- // Act and assert
- assert.throws(getWorkspaceRoot, /Workspace root should be defined/);
- });
+ it("will do nothing when it can't find a directory.", async function () {
+ // given this base folder...
+ const wsFolder = '/dev/some-empty-folder';
+ pushWorkspace(wsFolder);
- it('should return `undefined` when no workspace is opened and has `ignoreException`', () => {
- // Arrange
- workspaceMock.value(undefined);
+ // when I call the workspace resolver...
+ const workspaceRet = await AW.getWorkspaceForUri();
+ // then
+ expect(workspaceRet.dirName).to.be.eq('some-empty-folder');
+ expect(workspaceRet.workspaceType).to.be.eq(AW.WorkspaceType.UNKNOWN);
+ });
- // Act
- const result = getWorkspaceRoot(true);
+ it('will show quickpick if multiple workspace found - URI passed in.', async function () {
+ // given we get no workspaces back
+ const wsFolder = '/blah/shmah/some-empty-folder';
+ pushWorkspace(wsFolder);
+ sandbox.stub(AW, 'findWorkspaces').returns([aw1, aw2]);
+ quickPickStub.resolves({workspace: aw1} as QuickPickType);
+
+ // when I try and get the workspace
+ const workspaceRet = await AW.getWorkspaceForUri(Uri.file(wsFolder));
+ // then I am going to hit the quickpick and return the one from there...
+ expect(workspaceRet).to.be.not.undefined;
+ expect(workspaceRet.workspace.path).to.be.eq('/dev/unknown-aw1');
+ expect(workspaceRet.dirName).to.be.eq('unknown-aw1');
+ expect(workspaceRet.workspaceType).to.be.eq(WorkspaceType.UNKNOWN);
+ expect(workspaceRet.configName).to.be.eq(aw1.configName);
+ expect(quickPickStub.calledOnce).to.be.true;
+ });
- // Assert
- assert.strictEqual(result, undefined);
+ it('will show quickpick if multiple workspace found - no URI passed in.', async function () {
+ // given - I despair about testing in JS land and Sinon is about as useful as a chocolate fireguard...
+ pushWorkspace('/dev/some-empty-folder');
+ globStub.withArgs().callsFake(function (pattern: string): string[] {
+ if (pattern.includes('hardhat')) {
+ return ['hardhat1/hh-config.ts', 'hardhat2/hh-config.ts'];
+ }
+ return [];
});
+ quickPickStub.resolves({workspace: aw2} as QuickPickType);
- it('should return `undefined` when workspace is empty and has `ignoreException`', () => {
- // Arrange
- workspaceMock.value([]);
+ // when I try and get the workspace
+ const workspaceRet = await AW.getWorkspaceForUri();
- // Act
- const result = getWorkspaceRoot(true);
+ // then I am going to hit the quickpick and return the one from there...
+ expect(workspaceRet).to.be.not.undefined;
+ expect(workspaceRet.workspaceType).to.be.eq(aw2.workspaceType);
+ expect(workspaceRet.workspace.fsPath).to.be.eq(aw2.workspace.fsPath);
+ expect(quickPickStub.calledOnce).to.be.true;
+ });
- // Assert
- assert.strictEqual(result, undefined);
- });
+ it('will throw error when no workspaces', async function () {
+ expect(AW.getWorkspaceForUri()).to.eventually.be.rejectedWith(Error, 'Workspace root should be defined');
+ });
- it('should return the first workspace root path', async () => {
- // Arrange
- workspaceMock.value(testWorkspaceFolder);
+ it('will return first when only 1 workspace found - no uri passed', async function () {
+ //given - I have the default value set.
+ const wsFolder = '/dev/hardhat-test';
+ setupTestScenario(wsFolder, AW.HARDHAT_CONFIG_GLOB);
- // Act
- const result = getWorkspaceRoot();
+ // when I try and get the workspace
+ const workspaceRet = await AW.getWorkspaceForUri();
- // Assert
- assert.strictEqual(result, testWorkspaceFolder[0].uri.fsPath);
- });
+ // then I am going to hit the quickpick and return the one from there...
+ expect(workspaceRet).to.be.not.undefined;
+ expect(workspaceRet.workspaceType).to.be.eq(WorkspaceType.HARDHAT);
+ expect(quickPickStub.notCalled).to.be.true;
});
- describe('getTruffleWorkspace', () => {
- it('should reject when no workspace is opened', () => {
- // Arrange
- workspaceMock.value(undefined);
+ it('will resolve all workspaces - 1 workspace - [UNKNOWN] - includeUnknown=true', async function () {
+ // given
+ pushWorkspace('/dev/test-folder-1');
+ // when
+ const workspaces = resolveAllWorkspaces(true);
+ // then
+ expect(workspaces).to.have.length(1);
+ expect(workspaces[0].dirName).to.be.eq('test-folder-1');
+ expect(workspaces[0].workspaceType).to.be.eq(WorkspaceType.UNKNOWN);
+ });
- // Act and assert
- assert.rejects(getTruffleWorkspace, /Workspace root should be defined/);
- });
+ it('will resolve all workspaces - 1 workspace - [UNKNOWN] - includeUnknown=false', async function () {
+ // given
+ pushWorkspace('/dev/test-folder-1');
+ // when
+ const workspaces = resolveAllWorkspaces(false);
+ // then
+ expect(workspaces).to.have.length(0);
+ });
- it('should reject when workspace is empty', () => {
- // Arrange
- workspaceMock.value([]);
+ it('will resolve all workspaces - 2 workspaces - [UNKNOWN, TRUFFLE] - includeUnknown=true', async function () {
+ // given
+ pushWorkspace('/dev/test-folder-1');
+ pushWorkspace('/dev/test-folder-2');
+ // map one to be truffle
+ globStub
+ .withArgs(sinon.match((arg: string) => new RegExp('.*?test-folder-2.*?truffle-config.*').test(arg)))
+ .returns(['test-folder-2/gosh-this-is-hard.js']);
+ globStub.returns([]);
+
+ // when
+ const workspaces = resolveAllWorkspaces(true);
+ // then
+ expect(workspaces).to.have.length(2);
+
+ expect(workspaces[0].dirName).to.be.eq('test-folder-1');
+ expect(workspaces[0].workspaceType).to.be.eq(WorkspaceType.UNKNOWN);
+
+ expect(workspaces[1].dirName).to.be.eq('test-folder-2');
+ expect(workspaces[1].configName).to.be.eq('gosh-this-is-hard.js');
+ expect(workspaces[1].workspaceType).to.be.eq(WorkspaceType.TRUFFLE);
+ });
- // Act and assert
- assert.rejects(getTruffleWorkspace, /Workspace root should be defined/);
- });
+ it('will resolve all workspaces - 2 workspaces - [UNKNOWN, TRUFFLE] - includeUnknown=false', async function () {
+ // given
+ pushWorkspace('/dev/test-folder-1');
+ pushWorkspace('/dev/test-folder-2');
+ // map one to be truffle
+ globStub
+ .withArgs(sinon.match((arg: string) => new RegExp('.*?test-folder-2.*?truffle-config.*').test(arg)))
+ .returns(['test-folder-2/gosh-this-is-hard.js']);
+ globStub.returns([]);
+
+ // when
+ const workspaces = resolveAllWorkspaces(false);
+ // then
+ expect(workspaces).to.have.length(1);
+ expect(workspaces[0].dirName).to.be.eq('test-folder-2');
+ expect(workspaces[0].configName).to.be.eq('gosh-this-is-hard.js');
+ expect(workspaces[0].workspaceType).to.be.eq(WorkspaceType.TRUFFLE);
});
});
diff --git a/yarn.lock b/yarn.lock
index 9806927d..a977ecf5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -955,29 +955,42 @@
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz"
integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
-"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.7.0":
+"@sinonjs/commons@^1.7.0":
version "1.8.3"
resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz"
integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==
dependencies:
type-detect "4.0.8"
-"@sinonjs/formatio@^3.2.1":
- version "3.2.2"
- resolved "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz"
- integrity sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==
+"@sinonjs/commons@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3"
+ integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==
dependencies:
- "@sinonjs/commons" "^1"
- "@sinonjs/samsam" "^3.1.0"
+ type-detect "4.0.8"
-"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.3":
- version "3.3.3"
- resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz"
- integrity sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==
+"@sinonjs/fake-timers@^7.0.4":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5"
+ integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==
dependencies:
- "@sinonjs/commons" "^1.3.0"
- array-from "^2.1.1"
- lodash "^4.17.15"
+ "@sinonjs/commons" "^1.7.0"
+
+"@sinonjs/fake-timers@^9.1.2":
+ version "9.1.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c"
+ integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==
+ dependencies:
+ "@sinonjs/commons" "^1.7.0"
+
+"@sinonjs/samsam@^7.0.1":
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-7.0.1.tgz#5b5fa31c554636f78308439d220986b9523fc51f"
+ integrity sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==
+ dependencies:
+ "@sinonjs/commons" "^2.0.0"
+ lodash.get "^4.4.2"
+ type-detect "^4.0.8"
"@sinonjs/text-encoding@^0.7.1":
version "0.7.1"
@@ -2020,6 +2033,18 @@
resolved "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz"
integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==
+"@types/chai-as-promised@^7.1.5":
+ version "7.1.5"
+ resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255"
+ integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==
+ dependencies:
+ "@types/chai" "*"
+
+"@types/chai@*", "@types/chai@^4.3.4":
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4"
+ integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==
+
"@types/connect@*":
version "3.4.35"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
@@ -2329,10 +2354,17 @@
"@types/mime" "*"
"@types/node" "*"
-"@types/sinon@^7.0.11":
- version "7.5.2"
- resolved "https://registry.npmjs.org/@types/sinon/-/sinon-7.5.2.tgz"
- integrity sha512-T+m89VdXj/eidZyejvmoP9jivXgBDdkOSBVQjU9kF349NEx10QdPNGxHeZUaj1IlJ32/ewdyXJjnJxyxJroYwg==
+"@types/sinon@^10.0.13":
+ version "10.0.13"
+ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.13.tgz#60a7a87a70d9372d0b7b38cc03e825f46981fb83"
+ integrity sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==
+ dependencies:
+ "@types/sinonjs__fake-timers" "*"
+
+"@types/sinonjs__fake-timers@*":
+ version "8.1.2"
+ resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz#bf2e02a3dbd4aecaf95942ecd99b7402e03fad5e"
+ integrity sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==
"@types/source-map@^0.5.2":
version "0.5.7"
@@ -2822,11 +2854,6 @@ amdefine@>=0.0.4:
resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz"
integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
-ansi-colors@3.2.3:
- version "3.2.3"
- resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz"
- integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==
-
ansi-colors@4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz"
@@ -2854,11 +2881,6 @@ ansi-regex@^3.0.0:
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
-ansi-regex@^4.1.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz"
- integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
-
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
@@ -2869,7 +2891,7 @@ ansi-styles@^2.2.1:
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
-ansi-styles@^3.2.0, ansi-styles@^3.2.1:
+ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
@@ -3077,11 +3099,6 @@ array-flatten@1.1.1:
resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz"
integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
-array-from@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz"
- integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=
-
array-ify@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz"
@@ -3146,6 +3163,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+assertion-error@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
+ integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
+
assign-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz"
@@ -3763,7 +3785,7 @@ camelcase@^4.1.0:
resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz"
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
-camelcase@^5.0.0, camelcase@^5.3.1:
+camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
@@ -3808,6 +3830,26 @@ cbor@^5.1.0, cbor@^5.2.0:
bignumber.js "^9.0.1"
nofilter "^1.0.4"
+chai-as-promised@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0"
+ integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==
+ dependencies:
+ check-error "^1.0.2"
+
+chai@^4.3.7:
+ version "4.3.7"
+ resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51"
+ integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==
+ dependencies:
+ assertion-error "^1.1.0"
+ check-error "^1.0.2"
+ deep-eql "^4.1.2"
+ get-func-name "^2.0.0"
+ loupe "^2.3.1"
+ pathval "^1.1.1"
+ type-detect "^4.0.5"
+
chainsaw@~0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz"
@@ -3880,6 +3922,11 @@ chardet@^0.4.0:
resolved "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz"
integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=
+check-error@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
+ integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
+
cheerio-select@^1.5.0:
version "1.5.0"
resolved "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz"
@@ -4004,15 +4051,6 @@ cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
-cliui@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz"
- integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
- dependencies:
- string-width "^3.1.0"
- strip-ansi "^5.2.0"
- wrap-ansi "^5.1.0"
-
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz"
@@ -4508,14 +4546,7 @@ debug@3.1.0:
dependencies:
ms "2.0.0"
-debug@3.2.6:
- version "3.2.6"
- resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz"
- integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
- dependencies:
- ms "^2.1.1"
-
-debug@4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
+debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -4551,7 +4582,7 @@ decamelize-keys@^1.1.0:
decamelize "^1.1.0"
map-obj "^1.0.0"
-decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0:
+decamelize@^1.1.0, decamelize@^1.1.1:
version "1.2.0"
resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
@@ -4638,6 +4669,13 @@ dedent@^0.7.0:
resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz"
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
+deep-eql@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.2.tgz#270ceb902f87724077e6f6449aed81463f42fc1c"
+ integrity sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==
+ dependencies:
+ type-detect "^4.0.0"
+
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
@@ -4666,7 +4704,7 @@ deferred-leveldown@~5.3.0:
abstract-leveldown "~6.2.1"
inherits "^2.0.3"
-define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4:
+define-properties@^1.1.3, define-properties@^1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz"
integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
@@ -4758,11 +4796,6 @@ detect-libc@^1.0.2:
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
-diff@3.5.0, diff@^3.5.0:
- version "3.5.0"
- resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz"
- integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
-
diff@5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz"
@@ -4773,6 +4806,11 @@ diff@^4.0.1:
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+diff@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
+ integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==
+
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz"
@@ -4964,11 +5002,6 @@ emoji-regex@^10.1.0:
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz"
integrity sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==
-emoji-regex@^7.0.1:
- version "7.0.3"
- resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz"
- integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
-
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
@@ -5040,7 +5073,7 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5, es-abstract@^1.20.0:
+es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0:
version "1.20.1"
resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz"
integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
@@ -5119,16 +5152,16 @@ escape-html@~1.0.3:
resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
-escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
- integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
-
escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+
escodegen@1.8.x:
version "1.8.1"
resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz"
@@ -5854,13 +5887,6 @@ finalhandler@1.2.0:
statuses "2.0.1"
unpipe "~1.0.0"
-find-up@3.0.0, find-up@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz"
- integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
- dependencies:
- locate-path "^3.0.0"
-
find-up@5.0.0, find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
@@ -5884,6 +5910,13 @@ find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
+find-up@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz"
+ integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
+ dependencies:
+ locate-path "^3.0.0"
+
find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
@@ -5910,13 +5943,6 @@ flat-cache@^3.0.4:
flatted "^3.1.0"
rimraf "^3.0.2"
-flat@^4.1.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz"
- integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==
- dependencies:
- is-buffer "~2.0.3"
-
flat@^5.0.2:
version "5.0.2"
resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz"
@@ -6183,11 +6209,16 @@ get-caller-file@^1.0.1:
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz"
integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
-get-caller-file@^2.0.1, get-caller-file@^2.0.5:
+get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+get-func-name@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
+ integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
+
get-installed-path@^2.0.3:
version "2.1.1"
resolved "https://registry.npmjs.org/get-installed-path/-/get-installed-path-2.1.1.tgz"
@@ -6305,18 +6336,6 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
-glob@7.1.3:
- version "7.1.3"
- resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz"
- integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.0.4"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
glob@7.2.0, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.0"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz"
@@ -6600,7 +6619,7 @@ has-symbol-support-x@^1.4.1:
resolved "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz"
integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
-has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3:
+has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
@@ -7051,7 +7070,7 @@ is-buffer@^1.1.5:
resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-is-buffer@^2.0.5, is-buffer@~2.0.3:
+is-buffer@^2.0.5:
version "2.0.5"
resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
@@ -7493,14 +7512,6 @@ js-tokens@^3.0.2:
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
-js-yaml@3.13.1:
- version "3.13.1"
- resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz"
- integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
- dependencies:
- argparse "^1.0.7"
- esprima "^4.0.0"
-
js-yaml@3.x, js-yaml@^3.13.1, js-yaml@^3.9.1:
version "3.14.1"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
@@ -7990,6 +8001,11 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6:
resolved "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz"
integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==
+lodash.get@^4.4.2:
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+ integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
+
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
@@ -8005,13 +8021,6 @@ lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-log-symbols@2.2.0, log-symbols@^2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz"
- integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
- dependencies:
- chalk "^2.0.1"
-
log-symbols@4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz"
@@ -8027,6 +8036,13 @@ log-symbols@^1.0.2:
dependencies:
chalk "^1.0.0"
+log-symbols@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz"
+ integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
+ dependencies:
+ chalk "^2.0.1"
+
log-update@^2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz"
@@ -8041,18 +8057,6 @@ loglevel@^1.6.8:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114"
integrity sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==
-lolex@^4.2.0:
- version "4.2.0"
- resolved "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz"
- integrity sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==
-
-lolex@^5.0.1:
- version "5.1.2"
- resolved "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz"
- integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==
- dependencies:
- "@sinonjs/commons" "^1.7.0"
-
long@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
@@ -8065,6 +8069,13 @@ loose-envify@^1.1.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
+loupe@^2.3.1:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3"
+ integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==
+ dependencies:
+ get-func-name "^2.0.0"
+
lower-case-first@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz"
@@ -8337,13 +8348,6 @@ minimalistic-crypto-utils@^1.0.1:
dependencies:
brace-expansion "^1.1.7"
-minimatch@3.0.4:
- version "3.0.4"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"
- integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
- dependencies:
- brace-expansion "^1.1.7"
-
minimatch@4.2.1:
version "4.2.1"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz"
@@ -8351,6 +8355,13 @@ minimatch@4.2.1:
dependencies:
brace-expansion "^1.1.7"
+minimatch@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
+ integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
+ dependencies:
+ brace-expansion "^2.0.1"
+
minimatch@^5.0.1:
version "5.1.0"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz"
@@ -8407,13 +8418,6 @@ mkdirp@*, mkdirp@^1.0.4:
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
-mkdirp@0.5.4:
- version "0.5.4"
- resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz"
- integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==
- dependencies:
- minimist "^1.2.5"
-
mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1:
version "0.5.5"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz"
@@ -8458,34 +8462,32 @@ mocha@9.2.2:
yargs-parser "20.2.4"
yargs-unparser "2.0.0"
-mocha@^6.2.3:
- version "6.2.3"
- resolved "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz"
- integrity sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==
+mocha@^10.0.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.1.0.tgz#dbf1114b7c3f9d0ca5de3133906aea3dfc89ef7a"
+ integrity sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==
dependencies:
- ansi-colors "3.2.3"
+ ansi-colors "4.1.1"
browser-stdout "1.3.1"
- debug "3.2.6"
- diff "3.5.0"
- escape-string-regexp "1.0.5"
- find-up "3.0.0"
- glob "7.1.3"
- growl "1.10.5"
+ chokidar "3.5.3"
+ debug "4.3.4"
+ diff "5.0.0"
+ escape-string-regexp "4.0.0"
+ find-up "5.0.0"
+ glob "7.2.0"
he "1.2.0"
- js-yaml "3.13.1"
- log-symbols "2.2.0"
- minimatch "3.0.4"
- mkdirp "0.5.4"
- ms "2.1.1"
- node-environment-flags "1.0.5"
- object.assign "4.1.0"
- strip-json-comments "2.0.1"
- supports-color "6.0.0"
- which "1.3.1"
- wide-align "1.1.3"
- yargs "13.3.2"
- yargs-parser "13.1.2"
- yargs-unparser "1.6.0"
+ js-yaml "4.1.0"
+ log-symbols "4.1.0"
+ minimatch "5.0.1"
+ ms "2.1.3"
+ nanoid "3.3.3"
+ serialize-javascript "6.0.0"
+ strip-json-comments "3.1.1"
+ supports-color "8.1.1"
+ workerpool "6.2.1"
+ yargs "16.2.0"
+ yargs-parser "20.2.4"
+ yargs-unparser "2.0.0"
mock-fs@^4.1.0:
version "4.14.0"
@@ -8507,11 +8509,6 @@ ms@2.0.0:
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
-ms@2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz"
- integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
-
ms@2.1.2, ms@^2.1.1:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
@@ -8603,6 +8600,11 @@ nanoid@3.3.1:
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz"
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
+nanoid@3.3.3:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
+ integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
+
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz"
@@ -8666,15 +8668,15 @@ nice-try@^1.0.4:
resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-nise@^1.5.2:
- version "1.5.3"
- resolved "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz"
- integrity sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==
+nise@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.2.tgz#a7b8909c216b3491fd4fc0b124efb69f3939b449"
+ integrity sha512-+gQjFi8v+tkfCuSCxfURHLhRhniE/+IaYbIphxAN2JRR9SHKhY8hgXpaXiYfHdw+gcGe4buxgbprBQFab9FkhA==
dependencies:
- "@sinonjs/formatio" "^3.2.1"
+ "@sinonjs/commons" "^2.0.0"
+ "@sinonjs/fake-timers" "^7.0.4"
"@sinonjs/text-encoding" "^0.7.1"
just-extend "^4.0.2"
- lolex "^5.0.1"
path-to-regexp "^1.7.0"
no-case@^2.2.0, no-case@^2.3.2:
@@ -8699,14 +8701,6 @@ node-cleanup@^2.1.2:
resolved "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz"
integrity sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=
-node-environment-flags@1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz"
- integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==
- dependencies:
- object.getownpropertydescriptors "^2.0.3"
- semver "^5.7.0"
-
node-fetch@2.6.7, node-fetch@^2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
@@ -8956,7 +8950,7 @@ object-inspect@^1.12.0, object-inspect@^1.9.0:
resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz"
integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
-object-keys@^1.0.11, object-keys@^1.1.1:
+object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
@@ -8968,16 +8962,6 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
-object.assign@4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz"
- integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
- dependencies:
- define-properties "^1.1.2"
- function-bind "^1.1.1"
- has-symbols "^1.0.0"
- object-keys "^1.0.11"
-
object.assign@^4.1.2:
version "4.1.2"
resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz"
@@ -8988,15 +8972,6 @@ object.assign@^4.1.2:
has-symbols "^1.0.1"
object-keys "^1.1.1"
-object.getownpropertydescriptors@^2.0.3:
- version "2.1.3"
- resolved "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz"
- integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.1"
-
object.pick@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz"
@@ -9366,6 +9341,11 @@ path-type@^4.0.0:
resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+pathval@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
+ integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
+
pause-stream@0.0.11:
version "0.0.11"
resolved "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz"
@@ -10227,11 +10207,6 @@ require-main-filename@^1.0.1:
resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz"
integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==
-require-main-filename@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz"
- integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
-
require-uncached@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz"
@@ -10540,7 +10515,7 @@ semver-compare@^1.0.0:
resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.7.0:
+"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0:
version "5.7.1"
resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -10737,18 +10712,17 @@ simple-git@^1.85.0:
dependencies:
debug "^4.0.1"
-sinon@^7.3.2:
- version "7.5.0"
- resolved "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz"
- integrity sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==
+sinon@^14.0.2:
+ version "14.0.2"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-14.0.2.tgz#585a81a3c7b22cf950762ac4e7c28eb8b151c46f"
+ integrity sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==
dependencies:
- "@sinonjs/commons" "^1.4.0"
- "@sinonjs/formatio" "^3.2.1"
- "@sinonjs/samsam" "^3.3.3"
- diff "^3.5.0"
- lolex "^4.2.0"
- nise "^1.5.2"
- supports-color "^5.5.0"
+ "@sinonjs/commons" "^2.0.0"
+ "@sinonjs/fake-timers" "^9.1.2"
+ "@sinonjs/samsam" "^7.0.1"
+ diff "^5.0.0"
+ nise "^5.1.2"
+ supports-color "^7.2.0"
slash@^3.0.0:
version "3.0.0"
@@ -11040,7 +11014,7 @@ string-argv@^0.1.1:
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz"
integrity sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA==
-string-width@^1.0.1, "string-width@^1.0.2 || 2":
+string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz"
integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
@@ -11066,15 +11040,6 @@ string-width@^2.1.0, string-width@^2.1.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
-string-width@^3.0.0, string-width@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz"
- integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
- dependencies:
- emoji-regex "^7.0.1"
- is-fullwidth-code-point "^2.0.0"
- strip-ansi "^5.1.0"
-
string.prototype.trimend@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz"
@@ -11135,13 +11100,6 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
-strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz"
- integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
- dependencies:
- ansi-regex "^4.1.0"
-
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
@@ -11197,16 +11155,16 @@ strip-indent@^3.0.0:
dependencies:
min-indent "^1.0.0"
-strip-json-comments@2.0.1, strip-json-comments@~2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz"
- integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
-
strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+strip-json-comments@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz"
+ integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
+
strip-outer@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz"
@@ -11224,13 +11182,6 @@ sublevel-pouchdb@7.3.0:
ltgt "2.2.1"
readable-stream "1.1.14"
-supports-color@6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz"
- integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==
- dependencies:
- has-flag "^3.0.0"
-
supports-color@8.1.1, supports-color@^8.0.0:
version "8.1.1"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz"
@@ -11250,14 +11201,14 @@ supports-color@^3.1.0:
dependencies:
has-flag "^1.0.0"
-supports-color@^5.3.0, supports-color@^5.5.0:
+supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies:
has-flag "^3.0.0"
-supports-color@^7.1.0:
+supports-color@^7.1.0, supports-color@^7.2.0:
version "7.2.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
@@ -11670,9 +11621,9 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
-type-detect@4.0.8:
+type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8:
version "4.0.8"
- resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
type-fest@^0.18.0:
@@ -12382,11 +12333,6 @@ which-module@^1.0.0:
resolved "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz"
integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==
-which-module@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz"
- integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
-
which-typed-array@^1.1.2:
version "1.1.8"
resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz"
@@ -12399,13 +12345,6 @@ which-typed-array@^1.1.2:
has-tostringtag "^1.0.0"
is-typed-array "^1.1.9"
-which@1.3.1, which@^1.1.1, which@^1.2.10, which@^1.2.14, which@^1.2.9, which@^1.3.1:
- version "1.3.1"
- resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz"
- integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
- dependencies:
- isexe "^2.0.0"
-
which@2.0.2, which@^2.0.1:
version "2.0.2"
resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
@@ -12413,12 +12352,12 @@ which@2.0.2, which@^2.0.1:
dependencies:
isexe "^2.0.0"
-wide-align@1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz"
- integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
+which@^1.1.1, which@^1.2.10, which@^1.2.14, which@^1.2.9, which@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz"
+ integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
dependencies:
- string-width "^1.0.2 || 2"
+ isexe "^2.0.0"
wide-align@^1.1.0:
version "1.1.5"
@@ -12452,6 +12391,11 @@ workerpool@6.2.0:
resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz"
integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==
+workerpool@6.2.1:
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
+ integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
+
wrap-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz"
@@ -12468,15 +12412,6 @@ wrap-ansi@^3.0.1:
string-width "^2.1.1"
strip-ansi "^4.0.0"
-wrap-ansi@^5.1.0:
- version "5.1.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz"
- integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
- dependencies:
- ansi-styles "^3.2.0"
- string-width "^3.0.0"
- strip-ansi "^5.0.0"
-
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
@@ -12584,11 +12519,6 @@ y18n@^3.2.1:
resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz"
integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==
-y18n@^4.0.0:
- version "4.0.3"
- resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz"
- integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
-
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"
@@ -12619,14 +12549,6 @@ yaml@^1.10.0:
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
-yargs-parser@13.1.2, yargs-parser@^13.1.2:
- version "13.1.2"
- resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz"
- integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
-
yargs-parser@20.2.4:
version "20.2.4"
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz"
@@ -12650,15 +12572,6 @@ yargs-parser@^21.0.0:
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
-yargs-unparser@1.6.0:
- version "1.6.0"
- resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz"
- integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==
- dependencies:
- flat "^4.1.0"
- lodash "^4.17.15"
- yargs "^13.3.0"
-
yargs-unparser@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz"
@@ -12669,22 +12582,6 @@ yargs-unparser@2.0.0:
flat "^5.0.2"
is-plain-obj "^2.1.0"
-yargs@13.3.2, yargs@^13.3.0:
- version "13.3.2"
- resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz"
- integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==
- dependencies:
- cliui "^5.0.0"
- find-up "^3.0.0"
- get-caller-file "^2.0.1"
- require-directory "^2.1.1"
- require-main-filename "^2.0.0"
- set-blocking "^2.0.0"
- string-width "^3.0.0"
- which-module "^2.0.0"
- y18n "^4.0.0"
- yargs-parser "^13.1.2"
-
yargs@16.2.0, yargs@^16.1.0:
version "16.2.0"
resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz"