mirror of
https://github.com/foambubble/foam.git
synced 2026-01-10 06:28:12 -05:00
Refactored grouped resource tree data provider to use new matcher
This commit is contained in:
@@ -109,4 +109,48 @@ export class FileListBasedMatcher implements IMatcher {
|
||||
async refresh() {
|
||||
this.files = (await this.listFiles()).map(f => f.path);
|
||||
}
|
||||
|
||||
static async createFromListFn(listFiles: () => Promise<URI[]>) {
|
||||
const files = await listFiles();
|
||||
return new FileListBasedMatcher(files, listFiles);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A matcher that includes all URIs passed to it
|
||||
*/
|
||||
export class AlwaysIncludeMatcher implements IMatcher {
|
||||
include: string[] = ['**/*'];
|
||||
exclude: string[] = [];
|
||||
match(files: URI[]): URI[] {
|
||||
return files;
|
||||
}
|
||||
|
||||
isMatch(uri: URI): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
refresh(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export class SubstringExcludeMatcher implements IMatcher {
|
||||
include: string[] = ['**/*'];
|
||||
exclude: string[] = [];
|
||||
constructor(exclude: string) {
|
||||
this.exclude = [exclude];
|
||||
}
|
||||
|
||||
match(files: URI[]): URI[] {
|
||||
return files.filter(f => this.isMatch(f));
|
||||
}
|
||||
|
||||
isMatch(uri: URI): boolean {
|
||||
return !uri.path.includes(this.exclude[0]);
|
||||
}
|
||||
|
||||
refresh(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
import {
|
||||
workspace,
|
||||
ExtensionContext,
|
||||
window,
|
||||
commands,
|
||||
RelativePattern,
|
||||
Uri,
|
||||
} from 'vscode';
|
||||
import { workspace, ExtensionContext, window, commands } from 'vscode';
|
||||
import { MarkdownResourceProvider } from './core/services/markdown-provider';
|
||||
import { bootstrap } from './core/model/foam';
|
||||
import { URI } from './core/model/uri';
|
||||
import {
|
||||
FileListBasedMatcher,
|
||||
GenericDataStore,
|
||||
} from './core/services/datastore';
|
||||
import { Logger } from './core/utils/log';
|
||||
|
||||
import { features } from './features';
|
||||
import { VsCodeOutputLogger, exposeLogger } from './services/logging';
|
||||
import { getIgnoredFilesSetting } from './settings';
|
||||
import { fromVsCodeUri, toVsCodeUri } from './utils/vsc-utils';
|
||||
import { AttachmentResourceProvider } from './core/services/attachment-provider';
|
||||
import { VsCodeWatcher } from './services/watcher';
|
||||
import { createMarkdownParser } from './core/services/markdown-parser';
|
||||
import VsCodeBasedParserCache from './services/cache';
|
||||
import { createMatcherAndDataStore } from './services/editor';
|
||||
|
||||
export async function activate(context: ExtensionContext) {
|
||||
const logger = new VsCodeOutputLogger();
|
||||
@@ -38,23 +26,12 @@ export async function activate(context: ExtensionContext) {
|
||||
}
|
||||
|
||||
// Prepare Foam
|
||||
const excludePatterns = new Map<string, string[]>();
|
||||
workspace.workspaceFolders.forEach(f => excludePatterns.set(f.name, []));
|
||||
|
||||
const excludes = getIgnoredFilesSetting().map(g => g.toString());
|
||||
for (const exclude of excludes) {
|
||||
const tokens = exclude.split('/');
|
||||
const matchesFolder = workspace.workspaceFolders.find(
|
||||
f => f.name === tokens[0]
|
||||
);
|
||||
if (matchesFolder) {
|
||||
excludePatterns.get(tokens[0]).push(tokens.slice(1).join('/'));
|
||||
} else {
|
||||
for (const [, value] of excludePatterns.entries()) {
|
||||
value.push(exclude);
|
||||
}
|
||||
}
|
||||
}
|
||||
const {
|
||||
matcher,
|
||||
dataStore,
|
||||
excludePatterns,
|
||||
} = await createMatcherAndDataStore(excludes);
|
||||
|
||||
Logger.info('Loading from directories:');
|
||||
for (const folder of workspace.workspaceFolders) {
|
||||
@@ -63,30 +40,6 @@ export async function activate(context: ExtensionContext) {
|
||||
Logger.info(' Exclude: ' + excludePatterns.get(folder.name).join(','));
|
||||
}
|
||||
|
||||
const listFiles = async () => {
|
||||
let files: Uri[] = [];
|
||||
for (const folder of workspace.workspaceFolders) {
|
||||
const uris = await workspace.findFiles(
|
||||
new RelativePattern(folder.uri.path, '**/*'),
|
||||
new RelativePattern(
|
||||
folder.uri.path,
|
||||
`{${excludePatterns.get(folder.name).join(',')}}`
|
||||
)
|
||||
);
|
||||
files = [...files, ...uris];
|
||||
}
|
||||
|
||||
return files.map(fromVsCodeUri);
|
||||
};
|
||||
|
||||
const readFile = async (uri: URI) =>
|
||||
(await workspace.fs.readFile(toVsCodeUri(uri))).toString();
|
||||
|
||||
const dataStore = new GenericDataStore(listFiles, readFile);
|
||||
|
||||
const files = await dataStore.list();
|
||||
|
||||
const matcher = new FileListBasedMatcher(files, listFiles);
|
||||
const watcher = new VsCodeWatcher(
|
||||
workspace.createFileSystemWatcher('**/*')
|
||||
);
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { FoamGraph } from '../../core/model/graph';
|
||||
import { createTestNote, createTestWorkspace } from '../../test/test-utils';
|
||||
import { isOrphan } from './orphans';
|
||||
|
||||
const orphanA = createTestNote({
|
||||
uri: '/path/orphan-a.md',
|
||||
title: 'Orphan A',
|
||||
});
|
||||
|
||||
const nonOrphan1 = createTestNote({
|
||||
uri: '/path/non-orphan-1.md',
|
||||
});
|
||||
|
||||
const nonOrphan2 = createTestNote({
|
||||
uri: '/path/non-orphan-2.md',
|
||||
links: [{ slug: 'non-orphan-1' }],
|
||||
});
|
||||
|
||||
const workspace = createTestWorkspace()
|
||||
.set(orphanA)
|
||||
.set(nonOrphan1)
|
||||
.set(nonOrphan2);
|
||||
const graph = FoamGraph.fromWorkspace(workspace);
|
||||
|
||||
describe('isOrphan', () => {
|
||||
it('should return true when a note with no connections is provided', () => {
|
||||
expect(isOrphan(orphanA.uri, graph)).toBeTruthy();
|
||||
});
|
||||
it('should return false when a note with connections is provided', () => {
|
||||
expect(isOrphan(nonOrphan1.uri, graph)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { Foam } from '../../core/model/foam';
|
||||
import { FoamGraph } from '../../core/model/graph';
|
||||
import { URI } from '../../core/model/uri';
|
||||
import { createMatcherAndDataStore } from '../../services/editor';
|
||||
import { getOrphansConfig } from '../../settings';
|
||||
import { FoamFeature } from '../../types';
|
||||
import {
|
||||
@@ -9,7 +8,6 @@ import {
|
||||
ResourceTreeItem,
|
||||
UriTreeItem,
|
||||
} from '../../utils/grouped-resources-tree-data-provider';
|
||||
import { fromVsCodeUri } from '../../utils/vsc-utils';
|
||||
|
||||
const feature: FoamFeature = {
|
||||
activate: async (
|
||||
@@ -18,24 +16,24 @@ const feature: FoamFeature = {
|
||||
) => {
|
||||
const foam = await foamPromise;
|
||||
|
||||
const workspacesURIs = vscode.workspace.workspaceFolders.map(dir =>
|
||||
fromVsCodeUri(dir.uri)
|
||||
const { matcher } = await createMatcherAndDataStore(
|
||||
getOrphansConfig().exclude
|
||||
);
|
||||
|
||||
const provider = new GroupedResourcesTreeDataProvider(
|
||||
'orphans',
|
||||
'orphan',
|
||||
getOrphansConfig(),
|
||||
workspacesURIs,
|
||||
() => foam.graph.getAllNodes().filter(uri => isOrphan(uri, foam.graph)),
|
||||
() =>
|
||||
foam.graph
|
||||
.getAllNodes()
|
||||
.filter(uri => foam.graph.getConnections(uri).length === 0),
|
||||
uri => {
|
||||
if (uri.isPlaceholder()) {
|
||||
return new UriTreeItem(uri);
|
||||
}
|
||||
const resource = foam.workspace.find(uri);
|
||||
return new ResourceTreeItem(resource, foam.workspace);
|
||||
}
|
||||
return uri.isPlaceholder()
|
||||
? new UriTreeItem(uri)
|
||||
: new ResourceTreeItem(foam.workspace.find(uri), foam.workspace);
|
||||
},
|
||||
matcher
|
||||
);
|
||||
provider.setGroupBy(getOrphansConfig().groupBy);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.window.registerTreeDataProvider('foam-vscode.orphans', provider),
|
||||
@@ -45,7 +43,4 @@ const feature: FoamFeature = {
|
||||
},
|
||||
};
|
||||
|
||||
export const isOrphan = (uri: URI, graph: FoamGraph) =>
|
||||
graph.getConnections(uri).length === 0;
|
||||
|
||||
export default feature;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { Foam } from '../../core/model/foam';
|
||||
import { createMatcherAndDataStore } from '../../services/editor';
|
||||
import { getPlaceholdersConfig } from '../../settings';
|
||||
import { FoamFeature } from '../../types';
|
||||
import {
|
||||
GroupedResourcesTreeDataProvider,
|
||||
UriTreeItem,
|
||||
} from '../../utils/grouped-resources-tree-data-provider';
|
||||
import { fromVsCodeUri } from '../../utils/vsc-utils';
|
||||
|
||||
const feature: FoamFeature = {
|
||||
activate: async (
|
||||
@@ -14,19 +14,19 @@ const feature: FoamFeature = {
|
||||
foamPromise: Promise<Foam>
|
||||
) => {
|
||||
const foam = await foamPromise;
|
||||
const workspacesURIs = vscode.workspace.workspaceFolders.map(dir =>
|
||||
fromVsCodeUri(dir.uri)
|
||||
const { matcher } = await createMatcherAndDataStore(
|
||||
getPlaceholdersConfig().exclude
|
||||
);
|
||||
const provider = new GroupedResourcesTreeDataProvider(
|
||||
'placeholders',
|
||||
'placeholder',
|
||||
getPlaceholdersConfig(),
|
||||
workspacesURIs,
|
||||
() => foam.graph.getAllNodes().filter(uri => uri.isPlaceholder()),
|
||||
uri => {
|
||||
return new UriTreeItem(uri);
|
||||
}
|
||||
},
|
||||
matcher
|
||||
);
|
||||
provider.setGroupBy(getPlaceholdersConfig().groupBy);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.window.registerTreeDataProvider(
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { isEmpty } from 'lodash';
|
||||
import { asAbsoluteUri, URI } from '../core/model/uri';
|
||||
import { TextEncoder } from 'util';
|
||||
import {
|
||||
FileType,
|
||||
RelativePattern,
|
||||
Selection,
|
||||
SnippetString,
|
||||
TextDocument,
|
||||
Uri,
|
||||
ViewColumn,
|
||||
window,
|
||||
workspace,
|
||||
@@ -13,6 +16,13 @@ import {
|
||||
import { focusNote } from '../utils';
|
||||
import { fromVsCodeUri, toVsCodeUri } from '../utils/vsc-utils';
|
||||
import { isSome } from '../core/utils';
|
||||
import {
|
||||
AlwaysIncludeMatcher,
|
||||
FileListBasedMatcher,
|
||||
GenericDataStore,
|
||||
IDataStore,
|
||||
IMatcher,
|
||||
} from '../core/services/datastore';
|
||||
|
||||
interface SelectionInfo {
|
||||
document: TextDocument;
|
||||
@@ -124,3 +134,54 @@ export function asAbsoluteWorkspaceUri(uri: URI): URI {
|
||||
const res = asAbsoluteUri(uri, folders);
|
||||
return res;
|
||||
}
|
||||
|
||||
export const createMatcherAndDataStore = async (
|
||||
excludes: string[]
|
||||
): Promise<{
|
||||
matcher: IMatcher;
|
||||
dataStore: IDataStore;
|
||||
excludePatterns: Map<string, string[]>;
|
||||
}> => {
|
||||
const excludePatterns = new Map<string, string[]>();
|
||||
workspace.workspaceFolders.forEach(f => excludePatterns.set(f.name, []));
|
||||
|
||||
for (const exclude of excludes) {
|
||||
const tokens = exclude.split('/');
|
||||
const matchesFolder = workspace.workspaceFolders.find(
|
||||
f => f.name === tokens[0]
|
||||
);
|
||||
if (matchesFolder) {
|
||||
excludePatterns.get(tokens[0]).push(tokens.slice(1).join('/'));
|
||||
} else {
|
||||
for (const [, value] of excludePatterns.entries()) {
|
||||
value.push(exclude);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const listFiles = async () => {
|
||||
let files: Uri[] = [];
|
||||
for (const folder of workspace.workspaceFolders) {
|
||||
const uris = await workspace.findFiles(
|
||||
new RelativePattern(folder.uri.path, '**/*'),
|
||||
new RelativePattern(
|
||||
folder.uri.path,
|
||||
`{${excludePatterns.get(folder.name).join(',')}}`
|
||||
)
|
||||
);
|
||||
files = [...files, ...uris];
|
||||
}
|
||||
|
||||
return files.map(fromVsCodeUri);
|
||||
};
|
||||
|
||||
const readFile = async (uri: URI) =>
|
||||
(await workspace.fs.readFile(toVsCodeUri(uri))).toString();
|
||||
|
||||
const dataStore = new GenericDataStore(listFiles, readFile);
|
||||
const matcher = isEmpty(excludes)
|
||||
? new AlwaysIncludeMatcher()
|
||||
: await FileListBasedMatcher.createFromListFn(listFiles);
|
||||
|
||||
return { matcher, dataStore, excludePatterns };
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
workspace,
|
||||
Selection,
|
||||
MarkdownString,
|
||||
version,
|
||||
ViewColumn,
|
||||
} from 'vscode';
|
||||
import matter from 'gray-matter';
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { FoamWorkspace } from '../core/model/workspace';
|
||||
import { OPEN_COMMAND } from '../features/commands/open-resource';
|
||||
import {
|
||||
GroupedResoucesConfigGroupBy,
|
||||
GroupedResourcesConfig,
|
||||
} from '../settings';
|
||||
import { createTestNote, strToUri } from '../test/test-utils';
|
||||
AlwaysIncludeMatcher,
|
||||
SubstringExcludeMatcher,
|
||||
} from '../core/services/datastore';
|
||||
import { OPEN_COMMAND } from '../features/commands/open-resource';
|
||||
import { GroupedResoucesConfigGroupBy } from '../settings';
|
||||
import { createTestNote } from '../test/test-utils';
|
||||
import {
|
||||
DirectoryTreeItem,
|
||||
GroupedResourcesTreeDataProvider,
|
||||
UriTreeItem,
|
||||
} from './grouped-resources-tree-data-provider';
|
||||
|
||||
const testMatcher = new SubstringExcludeMatcher('path-exclude');
|
||||
|
||||
describe('GroupedResourcesTreeDataProvider', () => {
|
||||
const matchingNote1 = createTestNote({ uri: '/path/ABC.md', title: 'ABC' });
|
||||
const matchingNote2 = createTestNote({
|
||||
@@ -32,25 +35,19 @@ describe('GroupedResourcesTreeDataProvider', () => {
|
||||
.set(excludedPathNote)
|
||||
.set(notMatchingNote);
|
||||
|
||||
// Mock config
|
||||
const config: GroupedResourcesConfig = {
|
||||
exclude: ['path-exclude/**/*'],
|
||||
groupBy: GroupedResoucesConfigGroupBy.Folder,
|
||||
};
|
||||
|
||||
it('should return the grouped resources as a folder tree', async () => {
|
||||
const provider = new GroupedResourcesTreeDataProvider(
|
||||
'length3',
|
||||
'note',
|
||||
config,
|
||||
[strToUri('')],
|
||||
() =>
|
||||
workspace
|
||||
.list()
|
||||
.filter(r => r.title.length === 3)
|
||||
.map(r => r.uri),
|
||||
uri => new UriTreeItem(uri)
|
||||
uri => new UriTreeItem(uri),
|
||||
testMatcher
|
||||
);
|
||||
provider.setGroupBy(GroupedResoucesConfigGroupBy.Folder);
|
||||
const result = await provider.getChildren();
|
||||
expect(result).toMatchObject([
|
||||
{
|
||||
@@ -72,15 +69,16 @@ describe('GroupedResourcesTreeDataProvider', () => {
|
||||
const provider = new GroupedResourcesTreeDataProvider(
|
||||
'length3',
|
||||
'note',
|
||||
config,
|
||||
[strToUri('')],
|
||||
() =>
|
||||
workspace
|
||||
.list()
|
||||
.filter(r => r.title.length === 3)
|
||||
.map(r => r.uri),
|
||||
uri => new UriTreeItem(uri)
|
||||
uri => new UriTreeItem(uri),
|
||||
testMatcher
|
||||
);
|
||||
provider.setGroupBy(GroupedResoucesConfigGroupBy.Folder);
|
||||
|
||||
const directory = new DirectoryTreeItem(
|
||||
'/path',
|
||||
[new UriTreeItem(matchingNote1.uri)],
|
||||
@@ -98,22 +96,19 @@ describe('GroupedResourcesTreeDataProvider', () => {
|
||||
});
|
||||
|
||||
it('should return the flattened resources', async () => {
|
||||
const mockConfig = {
|
||||
...config,
|
||||
groupBy: GroupedResoucesConfigGroupBy.Off,
|
||||
};
|
||||
const provider = new GroupedResourcesTreeDataProvider(
|
||||
'length3',
|
||||
'note',
|
||||
mockConfig,
|
||||
[strToUri('')],
|
||||
() =>
|
||||
workspace
|
||||
.list()
|
||||
.filter(r => r.title.length === 3)
|
||||
.map(r => r.uri),
|
||||
uri => new UriTreeItem(uri)
|
||||
uri => new UriTreeItem(uri),
|
||||
testMatcher
|
||||
);
|
||||
provider.setGroupBy(GroupedResoucesConfigGroupBy.Off);
|
||||
|
||||
const result = await provider.getChildren();
|
||||
expect(result).toMatchObject([
|
||||
{
|
||||
@@ -132,19 +127,19 @@ describe('GroupedResourcesTreeDataProvider', () => {
|
||||
});
|
||||
|
||||
it('should return the grouped resources without exclusion', async () => {
|
||||
const mockConfig = { ...config, exclude: [] };
|
||||
const provider = new GroupedResourcesTreeDataProvider(
|
||||
'length3',
|
||||
'note',
|
||||
mockConfig,
|
||||
[strToUri('')],
|
||||
() =>
|
||||
workspace
|
||||
.list()
|
||||
.filter(r => r.title.length === 3)
|
||||
.map(r => r.uri),
|
||||
uri => new UriTreeItem(uri)
|
||||
uri => new UriTreeItem(uri),
|
||||
new AlwaysIncludeMatcher()
|
||||
);
|
||||
provider.setGroupBy(GroupedResoucesConfigGroupBy.Folder);
|
||||
|
||||
const result = await provider.getChildren();
|
||||
expect(result).toMatchObject([
|
||||
expect.anything(),
|
||||
@@ -163,15 +158,15 @@ describe('GroupedResourcesTreeDataProvider', () => {
|
||||
const provider = new GroupedResourcesTreeDataProvider(
|
||||
'length3',
|
||||
description,
|
||||
config,
|
||||
[strToUri('')],
|
||||
() =>
|
||||
workspace
|
||||
.list()
|
||||
.filter(r => r.title.length === 3)
|
||||
.map(r => r.uri),
|
||||
uri => new UriTreeItem(uri)
|
||||
uri => new UriTreeItem(uri),
|
||||
testMatcher
|
||||
);
|
||||
provider.setGroupBy(GroupedResoucesConfigGroupBy.Folder);
|
||||
const result = await provider.getChildren();
|
||||
expect(result).toMatchObject([
|
||||
{
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import micromatch from 'micromatch';
|
||||
import {
|
||||
GroupedResourcesConfig,
|
||||
GroupedResoucesConfigGroupBy,
|
||||
} from '../settings';
|
||||
import { GroupedResoucesConfigGroupBy } from '../settings';
|
||||
import { getContainsTooltip, getNoteTooltip, isSome } from '../utils';
|
||||
import { OPEN_COMMAND } from '../features/commands/open-resource';
|
||||
import { toVsCodeUri } from './vsc-utils';
|
||||
import { URI } from '../core/model/uri';
|
||||
import { Resource } from '../core/model/note';
|
||||
import { FoamWorkspace } from '../core/model/workspace';
|
||||
import { IMatcher } from '../core/services/datastore';
|
||||
|
||||
/**
|
||||
* Provides the ability to expose a TreeDataExplorerView in VSCode. This class will
|
||||
@@ -82,13 +79,10 @@ export class GroupedResourcesTreeDataProvider
|
||||
constructor(
|
||||
private providerId: string,
|
||||
private resourceName: string,
|
||||
config: GroupedResourcesConfig,
|
||||
workspaceUris: URI[],
|
||||
private computeResources: () => Array<URI>,
|
||||
private createTreeItem: (item: URI) => GroupedResourceTreeItem
|
||||
private createTreeItem: (item: URI) => GroupedResourceTreeItem,
|
||||
private matcher: IMatcher
|
||||
) {
|
||||
this.groupBy = config.groupBy;
|
||||
this.exclude = this.getGlobs(workspaceUris, config.exclude);
|
||||
this.setContext();
|
||||
this.doComputeResources();
|
||||
}
|
||||
@@ -163,30 +157,10 @@ export class GroupedResourcesTreeDataProvider
|
||||
|
||||
private doComputeResources(): void {
|
||||
this.flatUris = this.computeResources()
|
||||
.filter(uri => !this.isMatch(uri))
|
||||
.filter(uri => this.matcher.isMatch(uri))
|
||||
.filter(isSome);
|
||||
}
|
||||
|
||||
private isMatch(uri: URI) {
|
||||
return micromatch.isMatch(uri.toFsPath(), this.exclude);
|
||||
}
|
||||
|
||||
private getGlobs(fsURI: URI[], globs: string[]): string[] {
|
||||
globs = globs.map(glob => (glob.startsWith('/') ? glob.slice(1) : glob));
|
||||
|
||||
const exclude: string[] = [];
|
||||
|
||||
for (const fsPath of fsURI) {
|
||||
let folder = fsPath.path.replace(/\\/g, '/');
|
||||
if (folder.substr(-1) === '/') {
|
||||
folder = folder.slice(0, -1);
|
||||
}
|
||||
exclude.push(...globs.map(g => `${folder}/${g}`));
|
||||
}
|
||||
|
||||
return exclude;
|
||||
}
|
||||
|
||||
private getUrisByDirectory(): UrisByDirectory {
|
||||
const resourcesByDirectory: UrisByDirectory = {};
|
||||
for (const uri of this.flatUris) {
|
||||
|
||||
12
yarn.lock
12
yarn.lock
@@ -2222,9 +2222,9 @@
|
||||
"@babel/types" "^7.3.0"
|
||||
|
||||
"@types/braces@*":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb"
|
||||
integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.1.tgz#5a284d193cfc61abb2e5a50d36ebbc50d942a32b"
|
||||
integrity sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==
|
||||
|
||||
"@types/dateformat@^3.0.1":
|
||||
version "3.0.1"
|
||||
@@ -2340,9 +2340,9 @@
|
||||
integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==
|
||||
|
||||
"@types/micromatch@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7"
|
||||
integrity sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw==
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.2.tgz#ce29c8b166a73bf980a5727b1e4a4d099965151d"
|
||||
integrity sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==
|
||||
dependencies:
|
||||
"@types/braces" "*"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user