mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Move query history into extension (#19794)
* initial * more * Remove connectionId * cleanup * cleanup * Remove core contributions, add to panel by default * Add enabled state * Update config * cleanup * Move * Remove newlines * update README
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
# Query History *(preview)*
|
||||
|
||||
Adds a Query History panel for viewing and running past executed queries.
|
||||
Adds a Query History view for viewing and running past executed queries.
|
||||
|
||||
### How do I view the history?
|
||||
|
||||
Query History is displayed as a tab in the tab panel, which is toggled by the **View: Toggle Panel** command.
|
||||
Query History is initially as a tab in the tab panel, which is toggled by the **View: Toggle Panel** or **Query History: Focus on Query History View** commands.
|
||||
|
||||

|
||||
|
||||
This view can be moved similar to other views into other view containers by dragging and dropping into the desired view container.
|
||||
|
||||
Initially this view will be empty but once you execute a query editor that will be captured in the window - with a separate row displayed for every query executed.
|
||||
|
||||

|
||||
@@ -18,6 +20,12 @@ Each row consists of 4 parts :
|
||||
- Connection Info : The Server and Database the query was executed against
|
||||
- Timestamp : The date and time the query was executed
|
||||
|
||||
### Disabling/Enabling Query History
|
||||
|
||||
Query History capture can be enabled/disabled in one of two ways :
|
||||
|
||||
1. Through the action button on the view container - this will be a ⏸️ when capture is enabled and clicking it will disable capture until re-enabled. When capture is disabled this button will be a ▶ and clicking it will enable capture until disabled.
|
||||
2. By running the **Query History: Pause Query History Capture** or **Query History: Start Query History Capture** commands from the command palette.
|
||||
### Query History row actions
|
||||
|
||||
Right clicking on a history row will bring up a menu with a number of actions available.
|
||||
@@ -42,16 +50,9 @@ This will permanently delete **ALL** history rows.
|
||||
|
||||
This action is also available from the command palette (**Query History: Clear All History**) and as an action button on the panel.
|
||||
|
||||
#### Pause/Start Query History Capture
|
||||
|
||||
This will Pause or Start Query History Capture. While paused no data will be stored for queries run.
|
||||
|
||||
This action is also available from the command palette (**Query History: Toggle Query History Capture**) and as an action button
|
||||
on the panel.
|
||||
|
||||
### Data Storage
|
||||
|
||||
Currently all information is stored in-memory and not persisted upon application exit.
|
||||
Currently all information is stored in-memory and not persisted upon application exit. There is no limit to the number of entries stored, new entries will be continuously added as long as capture is enabled unless entries are deleted or the entire history is cleared.
|
||||
|
||||
## Code of Conduct
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
4
extensions/query-history/images/history.svg
Normal file
4
extensions/query-history/images/history.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M15.4,4.9a8.3,8.3,0,0,1,0,6.2,9.009,9.009,0,0,1-1.7,2.6,9.009,9.009,0,0,1-2.6,1.7A8.112,8.112,0,0,1,8,16a7.509,7.509,0,0,1-2.6-.4,7.609,7.609,0,0,1-2.3-1.3,7.31,7.31,0,0,1-1.7-1.8L.7,11.4c-.1-.4-.3-.8-.4-1.3l1-.2a7.207,7.207,0,0,0,.9,2,8.716,8.716,0,0,0,1.6,1.7,6.9,6.9,0,0,0,1.9,1A6.184,6.184,0,0,0,8,15l1.9-.2,1.6-.8a4.9,4.9,0,0,0,1.4-1.1A4.9,4.9,0,0,0,14,11.5a7.976,7.976,0,0,0,.8-1.6A12.233,12.233,0,0,0,15,8a12.233,12.233,0,0,0-.2-1.9A7.976,7.976,0,0,0,14,4.5a4.9,4.9,0,0,0-1.1-1.4A4.9,4.9,0,0,0,11.5,2a4.61,4.61,0,0,0-1.6-.7A6.283,6.283,0,0,0,8,1a6.879,6.879,0,0,0-2,.3,5.292,5.292,0,0,0-1.7.8A4.708,4.708,0,0,0,2.8,3.4,4.6,4.6,0,0,0,1.7,5H4V6H0V2H1V4.1l.3-.4.3-.5A9.122,9.122,0,0,1,3.3,1.5,7.6,7.6,0,0,1,5.5.4,7.308,7.308,0,0,1,8,0a8.112,8.112,0,0,1,3.1.6,9.009,9.009,0,0,1,2.6,1.7A9.009,9.009,0,0,1,15.4,4.9Z" />
|
||||
<polygon points="8 3 8 7.3 10.9 10.1 10.1 10.9 7 7.7 7 3 8 3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1002 B |
@@ -1,61 +1,187 @@
|
||||
{
|
||||
"name": "query-history",
|
||||
"displayName": "%queryHistory.displayName%",
|
||||
"description": "%queryHistory.description%",
|
||||
"version": "0.2.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
|
||||
"icon": "images/extension.png",
|
||||
"aiKey": "AIF-37eefaf0-8022-4671-a3fb-64752724682e",
|
||||
"engines": {
|
||||
"vscode": "^1.30.1",
|
||||
"azdata": ">=1.12.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "queryHistory.clear",
|
||||
"title": "%queryHistory.clear%",
|
||||
"category": "%queryHistory.displayName%"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.toggleCapture",
|
||||
"title": "%queryHistory.toggleCapture%",
|
||||
"category": "%queryHistory.displayName%"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "queryHistory.clear"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.toggleCapture"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": { },
|
||||
"__metadata": {
|
||||
"id": "55",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
"publisherId": "Microsoft"
|
||||
}
|
||||
"name": "query-history",
|
||||
"displayName": "%queryHistory.displayName%",
|
||||
"description": "%queryHistory.description%",
|
||||
"version": "0.3.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
|
||||
"icon": "images/extension.png",
|
||||
"aiKey": "AIF-37eefaf0-8022-4671-a3fb-64752724682e",
|
||||
"engines": {
|
||||
"vscode": "*",
|
||||
"azdata": ">=1.38.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
"configuration": [
|
||||
{
|
||||
"type": "object",
|
||||
"title": "%queryHistory.displayName%",
|
||||
"properties": {
|
||||
"queryHistory.captureEnabled": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "%queryHistory.captureEnabledDesc%"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"commands": [
|
||||
{
|
||||
"command": "queryHistory.open",
|
||||
"title": "%queryHistory.open%",
|
||||
"category": "%queryHistory.displayName%"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.run",
|
||||
"title": "%queryHistory.run%",
|
||||
"category": "%queryHistory.displayName%"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.delete",
|
||||
"title": "%queryHistory.delete%",
|
||||
"category": "%queryHistory.displayName%"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.clear",
|
||||
"title": "%queryHistory.clear%",
|
||||
"category": "%queryHistory.displayName%",
|
||||
"icon": "$(clear-all)"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.disableCapture",
|
||||
"title": "%queryHistory.disableCapture%",
|
||||
"category": "%queryHistory.displayName%",
|
||||
"icon": "$(debug-pause)"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.enableCapture",
|
||||
"title": "%queryHistory.enableCapture%",
|
||||
"category": "%queryHistory.displayName%",
|
||||
"icon": "$(play)"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "queryHistory.open",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.run",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.delete",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.disableCapture",
|
||||
"when": "config.queryHistory.captureEnabled"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.enableCapture",
|
||||
"when": "!config.queryHistory.captureEnabled"
|
||||
}
|
||||
],
|
||||
"view/title": [
|
||||
{
|
||||
"command": "queryHistory.clear",
|
||||
"when": "view == queryHistory",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.disableCapture",
|
||||
"when": "view == queryHistory && config.queryHistory.captureEnabled",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.enableCapture",
|
||||
"when": "view == queryHistory && !config.queryHistory.captureEnabled",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"view/item/context": [
|
||||
{
|
||||
"command": "queryHistory.open",
|
||||
"when": "view == queryHistory",
|
||||
"group": "QueryHistory@1"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.run",
|
||||
"when": "view == queryHistory",
|
||||
"group": "QueryHistory@2"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.delete",
|
||||
"when": "view == queryHistory",
|
||||
"group": "QueryHistory@3"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.clear",
|
||||
"when": "view == queryHistory",
|
||||
"group": "QueryHistory@4"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.disableCapture",
|
||||
"when": "view == queryHistory && config.queryHistory.capatureEnabled",
|
||||
"group": "QueryHistory@5"
|
||||
},
|
||||
{
|
||||
"command": "queryHistory.enableCapture",
|
||||
"when": "view == queryHistory && !config.queryHistory.captureEnabled",
|
||||
"group": "QueryHistory@5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"views": {
|
||||
"queryHistory": [
|
||||
{
|
||||
"id": "queryHistory",
|
||||
"name": "%queryHistory.displayName%"
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewsWelcome": [
|
||||
{
|
||||
"view": "queryHistory",
|
||||
"contents": "%queryHistory.noEntries%"
|
||||
}
|
||||
],
|
||||
"viewsContainers": {
|
||||
"panel": [
|
||||
{
|
||||
"id": "queryHistory",
|
||||
"title": "%queryHistory.displayName%",
|
||||
"icon": "./images/history.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.11.7"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "55",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
"publisherId": "Microsoft"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
{
|
||||
"queryHistory.displayName": "Query History",
|
||||
"queryHistory.description": "View and run previously executed queries",
|
||||
"queryHistory.captureEnabledDesc": "Whether Query History capture is enabled. If false queries executed will not be captured.",
|
||||
"queryHistory.open": "Open Query",
|
||||
"queryHistory.run": "Run Query",
|
||||
"queryHistory.delete": "Delete",
|
||||
"queryHistory.clear": "Clear All History",
|
||||
"queryHistory.toggleCapture": "Toggle Query History Capture"
|
||||
"queryHistory.disableCapture": "Pause Query History Capture",
|
||||
"queryHistory.enableCapture": "Start Query History Capture",
|
||||
"queryHistory.noEntries": "No queries to display"
|
||||
}
|
||||
|
||||
@@ -3,15 +3,39 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { QueryHistoryNode } from './queryHistoryNode';
|
||||
import { QueryHistoryProvider } from './queryHistoryProvider';
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<void> {
|
||||
// Currently all the functionality for this is contained within the core ADS
|
||||
// code as the extensibility API doesn't currently support all the required
|
||||
// functionality (such as contributing tab panels)
|
||||
void vscode.commands.executeCommand('queryHistory.enableQueryHistory');
|
||||
}
|
||||
|
||||
export async function deactivate(): Promise<void> {
|
||||
|
||||
const provider = new QueryHistoryProvider();
|
||||
context.subscriptions.push(provider);
|
||||
context.subscriptions.push(vscode.window.registerTreeDataProvider('queryHistory', provider));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.open', async (node: QueryHistoryNode) => {
|
||||
return azdata.queryeditor.openQueryDocument(
|
||||
{
|
||||
content: node.queryText
|
||||
}, node.connectionProfile?.providerId);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.run', async (node: QueryHistoryNode) => {
|
||||
const doc = await azdata.queryeditor.openQueryDocument(
|
||||
{
|
||||
content: node.queryText
|
||||
}, node.connectionProfile?.providerId);
|
||||
await azdata.queryeditor.connect(doc.uri, node.connectionProfile?.connectionId || '');
|
||||
azdata.queryeditor.runQuery(doc.uri);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.delete', (node: QueryHistoryNode) => {
|
||||
provider.deleteNode(node);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.clear', () => {
|
||||
provider.clearAll();
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.disableCapture', async () => {
|
||||
return provider.setCaptureEnabled(false);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.enableCapture', async () => {
|
||||
return provider.setCaptureEnabled(true);
|
||||
}));
|
||||
}
|
||||
|
||||
22
extensions/query-history/src/queryHistoryNode.ts
Normal file
22
extensions/query-history/src/queryHistoryNode.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { removeNewLines } from './utils';
|
||||
|
||||
export class QueryHistoryNode extends vscode.TreeItem {
|
||||
constructor(
|
||||
public readonly queryText: string,
|
||||
public readonly connectionProfile: azdata.connection.ConnectionProfile | undefined,
|
||||
timestamp: Date,
|
||||
isSuccess: boolean
|
||||
) {
|
||||
super(removeNewLines(queryText), vscode.TreeItemCollapsibleState.None);
|
||||
this.iconPath = isSuccess ? new vscode.ThemeIcon('check', new vscode.ThemeColor('testing.iconPassed')) : new vscode.ThemeIcon('error', new vscode.ThemeColor('testing.iconFailed'));
|
||||
this.tooltip = queryText;
|
||||
this.description = connectionProfile ? `${connectionProfile.serverName}|${connectionProfile.databaseName} ${timestamp.toLocaleString()}` : timestamp.toLocaleString();
|
||||
}
|
||||
}
|
||||
80
extensions/query-history/src/queryHistoryProvider.ts
Normal file
80
extensions/query-history/src/queryHistoryProvider.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import { QueryHistoryNode } from './queryHistoryNode';
|
||||
|
||||
const QUERY_HISTORY_CONFIG_SECTION = 'queryHistory';
|
||||
const CAPTURE_ENABLED_CONFIG_SECTION = 'captureEnabled';
|
||||
const DEFAULT_CAPTURE_ENABLED = true;
|
||||
|
||||
export class QueryHistoryProvider implements vscode.TreeDataProvider<QueryHistoryNode>, vscode.Disposable {
|
||||
|
||||
private _onDidChangeTreeData: vscode.EventEmitter<QueryHistoryNode | undefined> = new vscode.EventEmitter<QueryHistoryNode | undefined>();
|
||||
readonly onDidChangeTreeData: vscode.Event<QueryHistoryNode | undefined> = this._onDidChangeTreeData.event;
|
||||
|
||||
private _queryHistoryNodes: QueryHistoryNode[] = [];
|
||||
private _captureEnabled: boolean = true;
|
||||
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
constructor() {
|
||||
this._disposables.push(azdata.queryeditor.registerQueryEventListener({
|
||||
onQueryEvent: async (type: azdata.queryeditor.QueryEventType, document: azdata.queryeditor.QueryDocument, args: azdata.ResultSetSummary | string | undefined, queryInfo?: azdata.queryeditor.IQueryInfo) => {
|
||||
if (this._captureEnabled && queryInfo && type === 'queryStop') {
|
||||
const queryText = queryInfo.queryText ?? '';
|
||||
const connProfile = await azdata.connection.getConnection(document.uri);
|
||||
const isError = queryInfo.messages.find(m => m.isError) ? false : true;
|
||||
// Add to the front of the list so the new item appears at the top
|
||||
this._queryHistoryNodes.unshift(new QueryHistoryNode(queryText, connProfile, new Date(), isError));
|
||||
this._onDidChangeTreeData.fire(undefined);
|
||||
}
|
||||
}
|
||||
}));
|
||||
this.updateCaptureEnabled();
|
||||
this._disposables.push(vscode.workspace.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(QUERY_HISTORY_CONFIG_SECTION)) {
|
||||
this.updateCaptureEnabled();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public clearAll(): void {
|
||||
this._queryHistoryNodes = [];
|
||||
this._onDidChangeTreeData.fire(undefined);
|
||||
}
|
||||
|
||||
public deleteNode(node: QueryHistoryNode): void {
|
||||
this._queryHistoryNodes = this._queryHistoryNodes.filter(n => n !== node);
|
||||
this._onDidChangeTreeData.fire(undefined);
|
||||
}
|
||||
public getTreeItem(node: QueryHistoryNode): vscode.TreeItem {
|
||||
return node;
|
||||
}
|
||||
|
||||
public getChildren(element?: QueryHistoryNode): QueryHistoryNode[] {
|
||||
// We only have top level items
|
||||
return this._queryHistoryNodes;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._disposables.forEach(d => d.dispose());
|
||||
}
|
||||
|
||||
private updateCaptureEnabled(): void {
|
||||
this._captureEnabled = vscode.workspace.getConfiguration(QUERY_HISTORY_CONFIG_SECTION).get(CAPTURE_ENABLED_CONFIG_SECTION) ?? DEFAULT_CAPTURE_ENABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether query history capture is currently enabled
|
||||
* @param enabled Whether capture is currently enabled
|
||||
* @returns A promise that resolves when the value is updated and persisted to configuration
|
||||
*/
|
||||
public async setCaptureEnabled(enabled: boolean): Promise<void> {
|
||||
this._captureEnabled = enabled;
|
||||
return vscode.workspace.getConfiguration(QUERY_HISTORY_CONFIG_SECTION).update(CAPTURE_ENABLED_CONFIG_SECTION, this._captureEnabled, vscode.ConfigurationTarget.Global);
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,5 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/azdata.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
|
||||
|
||||
13
extensions/query-history/src/utils.ts
Normal file
13
extensions/query-history/src/utils.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Removes all newlines from the given string, replacing them with spaces
|
||||
* @param str The original string
|
||||
* @returns The string with all newlines replaced by spaces
|
||||
*/
|
||||
export function removeNewLines(str: string): string {
|
||||
return str.replace(/\r\n/g, ' ').replace(/\n/g, ' ');
|
||||
}
|
||||
@@ -2,3 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@^12.11.7":
|
||||
version "12.20.52"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.52.tgz#2fd2dc6bfa185601b15457398d4ba1ef27f81251"
|
||||
integrity sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==
|
||||
|
||||
Reference in New Issue
Block a user